This specification defines an HTTP protocol binding for the xRegistry specification. This document will include just the HTTP-specific details and semantics, leaving the core specification to define the xRegistry generic processing model and semantics that apply to all protocols.
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>/versionsPATCH and POST /<GROUPS>/<GID>/<RESOURCES>/<RID>/versionsDELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/versionsGET /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>PATCH and PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
For clarity, OPTIONAL attributes (specification-defined and extensions) are OPTIONAL for clients to use, but the servers' responsibility will vary. Server-unknown extension attributes MUST be silently stored in the backing datastore. Specification-defined, and server-known extension attributes, MUST generate an error if the corresponding feature is not supported or enabled. However, as with all attributes, if accepting the attribute results in a bad state (such as exceeding a size limit, or results in a security issue), then the server MAY choose to reject the request.
In the pseudo JSON format snippets ? means the preceding item is OPTIONAL,
* means the preceding item MAY appear zero or more times, and + means the
preceding item MUST appear at least once. The presence of the # character
means the remaining portion of the line is a comment. Whitespace characters in
the JSON snippets are used for readability and are not normative.
When HTTP query parameters are discussed, they are presented as ?<NAME> where
<NAME> is the name of the query parameter.
See the core specification for details
about the use of <...> substitution values.
See the core specification for the list of xRegistry defined terms that might be used.
This specification defines the following base API patterns:
/ # Access the Registry
/capabilities # Access features enabled
/capabilitiesoffered # Access available features
/model # Access full model definitions
/modelsource # Access model customizations
/export # Retrieve Registry as a doc
/<GROUPS> # Access a Group Type
/<GROUPS>/<GID> # Access a Group
/<GROUPS>/<GID>/<RESOURCES> # Access a Resource Type
/<GROUPS>/<GID>/<RESOURCES>/<RID> # Default Version of Resource
/<GROUPS>/<GID>/<RESOURCES>/<RID>/meta # Access a Resource's metadata
/<GROUPS>/<GID>/<RESOURCES>/<RID>/versions # Versions of a Resource
/<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID> # Access Version of Resource
While these APIs are shown to be at the root path of a host, implementations MAY choose to prefix them as necessary. However, the same prefix MUST be used consistently for all APIs in the same Registry instance.
If an OPTIONAL HTTP path is not supported by an implementation, then any use of that API MUST generate an error (api_not_found).
If an HTTP method is not supported for a supported HTTP path, then an error (action_not_supported) MUST be generated.
Implementations MAY support extension APIs, however, the following rules apply:
For example, a new API with an HTTP path of /my-api is allowed, but APIs with
/model/my-api or /name HTTP paths are not.
This specification leans on the RFC9110 HTTP Semantics model with the RFC5789 PATCH extension. The following key aspects are called out to help understand the overall pattern of the APIs:
PUT or POST operation is a full replacement of the entities
processed. Any missing attributes MUST be interpreted as a request for them
to be deleted. However, attributes that are managed by the server might have
specialized processing in those cases, in particular, mandatory attributes,
as well as ones that have default values defined, MUST be reset to their
default values rather than deleted.PATCH operation MUST only modify the attributes explicitly mentioned
in the request. Any attribute in the request with a value of null MUST be
interpreted as a request to delete the attribute, and as with PUT/POST,
server-managed attributes might have specialized processing.PUT MUST NOT be targeted at xRegistry collections. A POST or PATCH
MUST be used instead to add entities to the collection, and a
DELETE MUST then be used to delete unwanted entities.PUT method is idempotent, this specification does not
adhere to that rule when it comes to the epoch and modifiedat attributes.
While multiple identical PUT requests will yield the same semantic effect
as single PUT for all other attributes, the epoch and modifiedat
attributes are designed to always be updated on each write operation to that
entity.In the core specification there is a
discussion about "no-code servers". In the
case of HTTP, simple file servers SHOULD support exposing Resources where the
HTTP body response contains the Resource's domain-specific "document" as well
exposing the serialization of the Resource's xRegistry metadata via the
$details suffix on the URL path. This can be achieved by creating a
secondary, sibling, file on disk with $details at the end of its filename.
This section mainly focuses on the successful interaction patterns of the APIs.
For example, most examples will show an HTTP "200 OK" as the response. Each
implementation MAY choose to return a more appropriate response based on the
specific situation. For example, in the case of an authentication error the
server could return 401 Unauthorized.
The following sections define the API in more detail.
Rather than repeating the processing rules for PATCH, POST and PUT,
for each type of xRegistry entity or Registry collection, the overall pattern
is defined once in this section and any entity-, or collection-specific rules
will be detailed in the appropriate section in the specification.
This defines the general rules for how to update entities.
Creating or updating entities MAY be done using HTTP PUT, PATCH or POST
methods:
PUT <PATH-TO-ENTITY> # Process a single entityPATCH <PATH-TO-ENTITY> # Process a single entityPOST <PATH-TO-ENTITY> # Process a set of child entitiesPATCH <PATH-TO-COLLECTION> # Process a set of entitiesPOST <PATH-TO-COLLECTION> # Process a set of entitiesSee the Request Flags section for the
list of flags/query parameters that MAY be used for each API.
The PUT variant MUST adhere to the following:
<PATH-TO-ENTITY>.null, MUST be interpreted as a request to delete the attribute.The PATCH variant when directed at a single entity, MUST adhere to the PUT
semantics defined above with the following exceptions:
null MUST be interpreted as
a request to delete the attribute.hasdocument model
aspect set to true, the URL accessing the entity MUST include the
$details suffix, and MUST generate an error
(details_required) in the absence of the
$details suffix. This is because when it is absent, the processing of
the HTTP xRegistry- headers are already defined with "PATCH" semantics
so a normal PUT or POST can be used instead. Using PATCH in this
case would mean that the request is trying to "patch" the Resource's
"document", which this specification does not support at this time.PATCH MAY be used to create new entities, but as with any of the create
operations, any missing REQUIRED attributes MUST generate an error
(required_attribute_missing).The POST variant when directed at a single entity other than a Resource,
MUST adhere to the following:
<SINGULAR>id and the value is a serialization of the entity
itself.POST to to nested xRegistry collection where the map
entry's value is the input.The POST variant when directed at a Resource entity, MUST adhere to the
following:
versionscount), and if they are present, then they MUST be silently
ignored by the server. This is done as a convenience for users who might
have obtained the Version's serialization from a query to a Resource (not
a specific Version), in which case those extra Resource-level would be
included in the serialization.The PATCH variant when directed at an xRegistry collection, MUST adhere to
the following:
<SINGULAR>id of each entity in the map. Note, that in the case of a map
of Versions, the versionid is used.PATCH of a single entity above.The POST variant when directed at an xRegistry collection MUST adhere to the
following:
<SINGULAR>id of each entity in the map. Note, that in the case of a map
of Versions, the versionid is used.POST does not support deleting
entities from a collection, so a separate delete operation might be needed
if there are entities that need to be removed.PUT above.The processing of each individual entity follows the same set of rules:
<SINGULAR>id already exists then it MUST be
interpreted as a request to update the existing entity. Otherwise, it MUST
be interpreted as a request to create a new entity with that <SINGULAR>id.<SINGULAR>id MUST be compared
with the entity's current value and if it differs then an error
(mismatched_id) MUST be generated. This includes
both <RESOURCE>id and versionid in the case of Resources and Versions.
This is to prevent accidentally updating the wrong entity.{} SHOULD be used instead.Resources and Versions have the following additional rules:
xRegistry- HTTP headers
MUST generate an error (extra_xregistry_header).<RESOURCE>url xRegistry HTTP header is present with a
non-null value, the HTTP body MUST be empty. If the <RESOURCE>url
attribute is absent, then the contents of the HTTP body (even if empty) are
to be used as the entity's document.<RESOURCE> and <RESOURCEbase64> attributes MUST never appear as
xRegistry HTTP headers, and if present on an write request MUST generate
an error (extra_xregistry_header).A successful response MUST return the same response as a GET to the entity
(or entities) processed, showing their current representation in the same
format ($details variant or not) as the request, with the
following exceptions:
POST case, or a PATCH directed to an xRegistry collection, the
result MUST contain only the entities processed, not the entire Registry
collection.PUT or PATCH cases that are directed to a single entity, for a
newly created entity, the HTTP status MUST be 201 Created, and it MUST
include an HTTP Location header with a URL to the newly created entity.
Note that this URL MUST be the same as the self attribute of that entity.PUT or PATCH cases directed at a single Resource or Version, if
a new Version was created, the response MUST include a Content-Location
HTTP header to the newly created Version entity, and it MUST be the same as
the Version's self attribute.<RESOURCE>, <RESOURCE>base64 or nested objects/collections) unless
requested.Otherwise an HTTP 200 OK without an HTTP Location header MUST be returned.
Note that the response MUST be generated applying the semantics of any
request flags specified in the request
URL (e.g. ?inline).
All API responses, including errors, SHOULD include a Link HTTP header of
the form:
Link: <URL-TO-XREGISTRY-ROOT>;rel=xregistry-root
Where URL-TO-XREGISTRY-ROOT is the URL to the root of the current xRegistry
instance.
This allows for client-side response processing to unambiguously know the base URL of the Registry from which the response came without needing to know the request URL or attempting to determine the URL from the response payload.
Examples:
Link: <https://myregistry.example.com>;rel=xregistry-root
self Attribute 🔗In addition to the core specification's definition of
self, the following HTTP-specific rules apply:
hasdocument aspect
is set to true, then this URL MUST include the $details suffix appended
to its <SINGULAR>id if it serialized in the the HTTP body response. If
the aspect is set to false then it MUST NOT include it. This rule applies
even if the URL used in a request message did include the suffix.labels Attribute 🔗In addition to the core specification's definition of
labels, the following HTTP-specific rules
apply:
labels is serialized as an HTTP header, see
Serializing Resource Domain-Specific Documents, then
each map entry MUST appear as a separate HTTP header using a name of
xRegistry-labels.<KEYNAME>.contenttype Attribute 🔗In addition to the core specification's definition of
contenttype, the following HTTP-specific
rules apply:
Content-Type and not xRegistry-contenttype.Content-Type HTTP header.<RESOURCE> Attribute 🔗In addition to the core specification's definition of
<RESOURCE>, the following HTTP-specific
rules apply:
<RESOURCE>base64 Attribute 🔗This attribute MUST NOT be present when the Resource/Version xRegistry
metadata is serialized as HTTP headers.
In addition to the core specification's definition of
<RESOURCE>base64, the following
HTTP-specific rules apply:
When a Resource or Version's attributes are serialized as HTTP headers, this attribute MUST NOT be included in the list.
Since xRegistry collections (i.e. the <COLLECTION> attribute) could be too
large to retrieve in a single request, when retrieving a collection, the
client MAY request a subset by using the
pagination specification. Likewise, the server MAY
choose to return a subset of the collection using the same mechanism defined
in that specification even if the request didn't ask for pagination. The
pagination specification MUST only be used when the request is directed at a
collection, not at its owning entity (such as the root of the Registry, or at
an individual Group or Resource).
In the remainder of this specification, the presence of the Link HTTP header
indicates the use of the pagination specification
MAY be used for that API.
A server MAY support clients querying the list of supported HTTP methods for any supported API. The request MUST be of the form:
OPTIONS <PATH>
A successful response MUST be of the form:
HTTP/1.1 200 OK
Allow: <METHODS>
Access-Control-Allow-Methods: <METHODS>
Where:
<METHODS> is a comma-separated list of HTTP methods that are supported
by that API.<METHODS> values MUST be returned for both headers.OPTIONS MUST be one of the values returned.Examples:
Retrieve supported list of HTTP method at the root of the Registry:
OPTIONS /
HTTP/1.1 200 OK
Allow: GET, OPTIONS
Access-Control-Allow-Methods: GET, OPTIONS
GET / 🔗A server MAY support clients retrieving
Registry Entity via an HTTP GET directed to
the Registry Entity.
See Registry Entity for more information.
The request MUST be of the form:
GET /
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
... Registry entity excluded for brevity ...
}
Examples:
Retrieve a Registry that has 2 types of Groups (endpoints and
schemagroups):
GET /
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"specversion": "1.0-rc2",
"registryid": "myRegistry",
"self": "https://example.com/",
"xid": "/",
"epoch": 1,
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"endpointsurl": "https://example.com/endpoints",
"endpointscount": 42,
"schemagroupsurl": "https://example.com/schemagroups",
"schemagroupscount": 1
}
PATCH and PUT / 🔗A server MAY support clients updating the
Registry entity via an HTTP PATCH or PUT
directed to the Registry entity.
The processing of these APIs is defined in the Creating or Updating Entities section.
The request MUST be of the form:
PUT /
Content-Type: application/json; charset=utf-8
or
PATCH /
Content-Type: application/json; charset=utf-8
{
... Registry entity excluded for brevity ...
}
Where:
capabilities, modelsource and Groups
attributes, the HTTP body MUST contain the full JSON representation of the
Registry entity's mutable attributes that are to be set, the rest will be
deleted.capabilities or modelsource attribute MUST NOT result in any
changes to those values.PATCH and PUT cases, if present, the modelsource attribute
MUST be a complete replacement representation of the model definition. A
value of null MUST reset the model to the server's default value.
See Creating or Updating the Registry
Model for more
information.capabilities attribute is present and PATCH is used then only
the top-level capabilities specified in the request MUST be updated. But,
each capability present MUST be specified in its entirety. When PUT is
used then it MUST be a complete replacement definition of all the
capabilities. In either case, a value of null MUST reset the server to
its default set of capabilities.A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
.. Registry entity excluded for brevity ...
}
Examples:
Updating a Registry's metadata:
PUT /
Content-Type: application/json; charset=utf-8
{
"registryid": "myRegistry",
"name": "My Registry",
"description": "An even cooler registry!"
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"specversion": "1.0-rc2",
"registryid": "myRegistry",
"self": "https://example.com/",
"xid": "/",
"epoch": 2,
"name": "My Registry",
"description": "An even cooler registry!",
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"endpointsurl": "https://example.com/endpoints",
"endpointscount": 42,
"schemagroupsurl": "https://example.com/schemagroups",
"schemagroupscount": 1
}
POST / 🔗A server MAY support clients updating or creating multiple
Groups of varying types via an HTTP POST directed
to the Registry entity. This API is very similar
to the POST /<GROUPS> API, except that the HTTP body
MUST be a map of Group types as shown below:
The request MUST be of the form:
POST /
Content-Type: application/json; charset=utf-8
{
# Repeat for each Group type that has a Group to be created or updated
"<GROUPS>": {
"<GROUPS>id": {
... Group entity excluded for brevity ...
} *
} *
}
Notice the format is almost the same as what a PUT / would look like if the
request wanted to update the Registry's attributes and define a set of Groups,
but without the Registry's attributes. This allows for an update of the
specified Groups without modifying the Registry's attributes.
A request that isn't a map of Group types (e.g. it contains other Registry level attributes) MUST generate an error (groups_only).
The response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"<GROUPS>": {
"<GROUPS>id": {
... Group entity excluded for brevity ...
} *
} *
}
}
Where:
Examples:
Creating 4 Groups of 2 different Group types.
POST /
Content-Type: application/json; charset=utf-8
{
"endpoints": {
"endpoint1": { ... Group endpoint1 excluded for brevity ... },
"endpoint2": { ... Group endpoint2 excluded for brevity ... }
},
"schemagroups": {
"schemagroup1": { ... Group schemagroup1 excluded for brevity ... },
"schemagroup2": { ... Group schemagroup2 excluded for brevity ... }
}
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"endpoints": {
"endpoint1": { ... Group endpoint1 excluded for brevity ... },
"endpoint2": { ... Group endpoint2 excluded for brevity ... }
},
"schemagroups": {
"schemagroup1": { ... Group schemagroup1 excluded for brevity ... },
"schemagroup2": { ... Group schemagroup2 excluded for brevity ... }
}
}
GET /export 🔗The GET /export API MUST be an alias for
GET /?doc&inline=*,capabilities,modelsource. If this path is supported,
it MUST NOT support any HTTP update methods. This API was created:
Request Flags MAY be included, if
supported, and any ?inline flag specified MUST override the
default value defined above.
A request MUST be of the form:
GET /export
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
... Registry entity, and nested collections, excluded for brevity ...
}
GET /capabilities 🔗A server SHOULD support clients retrieving the set of
capabilities(features) it supports via
an HTTP GET directed to the stand-alone capabilities map.
The request MUST be of the form:
GET /capabilities
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Capabilities map excluded for brevity ... }
Examples:
GET /capabilities
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"apis": [
"/capabilities", "/export", "/model", "/modelsource"
],
"flags": [
"binary", "collections", "doc", "epoch", "filter", "ignore", "inline",
"setdefaultversionid", "sort", "specversion"
],
"ignores": [ "capabilities", "defaultversionid", "defaultversionsticky",
"epoch", "id", "modelsource", "readonly"
],
"mutable": [ "capabilities", "entities", "model" ],
"pagination": false,
"shortself": false,
"specversions": [ "1.0-rc2" ],
"stickyversions": true
}
GET /capabilitiesoffered 🔗If a server supports clients updating its
capabilities, then it SHOULD support
clients retrieving the set of valid
offered capabilities it supports via an
HTTP GET directed to the stand-alone capabilitiesoffered map.
The request MUST be of the form:
GET /capabilitiesoffered
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Capabilities offering map excluded for brevity ... }
Examples:
GET /capabilitiesoffered
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"apis": {
"type": "array",
"item": {
"type": "string"
},
"enum": [ "/capabilities", "/capabilitiesoffered", "/export", "/model",
"/modelsource" ]
},
"flags": {
"type": "array",
"item": {
"type": "string"
},
"enum": [ "collections", "doc", "epoch", "filter", "ignore", "inline",
"setdefaultversionid", "sort", "specversion" ]
},
"ignores": {
"type": "array",
"item": {
"type": "string"
},
"enum": [ "capabilities", "defaultversionid", "defaultversionsticky",
"epoch", "id", "modelsource", "readonly" ]
},
"pagination": {
"type": "boolean",
"enum": [ false, true ]
},
"shortself": {
"type": "boolean",
"enum": [ false, true ]
},
"specversions": {
"type": "array",
"item": {
"type": "string"
},
"enum": [ "1.0-rc2" ]
},
"stickyversions": {
"type": "boolean",
"enum": [ true ]
},
"versionmodes": {
"type": "array",
"item": {
"type": "string"
},
"enum": [ "manual" ]
}
}
PATCH and PUT /capabilities 🔗A server MAY support clients updating its supported
capabilities (features)
via an HTTP PATCH or PUT directed to the stand-alone capabilities map.
A PUT MUST be interpreted as a request to update the entire set of
capabilities and any missing capability MUST be interpreted as a request to
reset it to its default value.
A PATCH is used to update a subset of capabilities. Each capability included
MUST be fully specified, and only those specified in the request MUST be fully
replaced by the incoming values. In other words, PATCH is done at a
capability level, not any deeper within the JSON structure.
See Updating the Capabilities of a Server for more information.
The request MUST be of the form:
PATCH /capabilities
Content-Type: application/json; charset=utf-8
or
PUT /capabilities
Content-Type: application/json; charset=utf-8
{ ... Capabilities map excluded for brevity... }
Where:
PUT, or the full representation of just the modified
capabilities in the case of PATCH.A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Capabilities map excluded for brevity ... }
Any change to the configuration of the server that is not supported MUST result in an error (capability_error) and no changes applied. Likewise, any unknown capability keys specified MUST generate an error (capability_error).
Note: per the Updating the Capabilities of a Server section, the semantic changes MUST NOT take effect until after the processing of the current request is completed, even though the response MUST show the requested changes.
Examples:
PATCH /capabilities
{
"shortself": true
}
{
"apis": [
"/capabilities", "/export", "/model", "/modelsource"
],
"flags": [
"binary", "collections", "doc", "epoch", "filter", "ignore", "inline",
"setdefaultversionid", "sort", "specversion"
],
"ignores": [
"capabilities", "defaultversionid", "defaultversionsticky", "epoch",
"id", "modelsource", "readonly"
],
"mutable": [ "capabilities", "entities", "model" ],
"pagination": false,
"shortself": true,
"specversions": [ "1.0-rc2" ],
"stickyversions": true
}
GET /model 🔗A server MAY support clients retrieving its full
model definition via an HTTP GET directed to
the stand-lone model entity.
The request MUST be of the form:
GET /model
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Model definition excluded for brevity ... }
To retrieve the model as part of the response to
retrieving the
Registry entity, use the
Inline Flag with a value of model.
Note that the /model API is a read-only API.
GET /modelsource 🔗A server MAY support clients retrieving the client-provided
model definition used to define the current
model via an HTTP GET directed to the stand-alone modelsource entity.
The request MUST be of the form:
GET /modelsource
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Model definition excluded for brevity ... }
To retrieve the modelsource as part of the response to
retrieving the
Registry entity, use the
Inline Flag with a value of modelsource.
PUT /modelsource 🔗A server MAY support clients updating its
model definition via an HTTP PUT directed to
the stand-alone modelsource entity.
The request MUST be of the form:
PUT /modelsource
Content-Type: application/json; charset=utf-8
{ ... Model definition excluded for brevity ... }
To update the modelsource as part of a request to update the
Registry entity, you can include the attribute
as part of the PUT / request.
GET /<GROUPS> 🔗A server MAY support clients retrieving a
Group collection via an HTTP GET directed to the
Registry's <GROUPS> collection URL.
The request MUST be of the form:
GET /<GROUPS>
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Link: <URL>;rel=next;count=<UINTEGER> ?
{
"<KEY>": { # <GROUP>id
... Group entity excluded for brevity ...
} *
}
Examples:
Retrieve all entities in the endpoints Group collection:
GET /endpoints
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Link: <https://example.com/endpoints&page=2>;rel=next;count=100
{
"ep1": {
"endpointid": "ep1",
"self": "https://example.com/endpoints/ep1",
"xid": "/endpoints/ep1",
"epoch": 1,
"name": "A cool endpoint",
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"messagesurl": "https://example.com/endpoints/ep1/messages",
"messagescount": 5
},
"ep2": {
"endpointid": "ep2",
"self": "https://example.com/endpoints/ep2",
"xid": "/endpoints/ep2",
"epoch": 3,
"name": "Redis Queue",
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"messagesurl": "https://example.com/endpoints/ep2/messages",
"messagescount": 1
}
}
Notice that the Link HTTP header is present, indicating that there
is a second page of results that can be retrieved via the specified URL,
and that there are a total of 100 items in this collection.
PATCH and POST /<GROUPS> 🔗A server MAY support clients creating/updating multiple
Groups in a Group collection via an HTTP PATCH or
POST directed to the Registry's <GROUPS> collection URL.
The processing of these APIs is defined in the Creating or Updating Entities section.
The request MUST be of the form:
PATCH /<GROUPS>
Content-Type: application/json; charset=utf-8
or
POST /<GROUPS>
Content-Type: application/json; charset=utf-8
{
"<KEY>": { # <GROUP>id
... Group entity excluded for brevity ...
} *
}
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"<KEY>": { # <GROUP>id
... Group entity excluded for brevity ...
} *
}
Examples:
POST /endpoints
Content-Type: application/json; charset=utf-8
{
"ep1": {
"endpointid": "ep1",
... remainder of ep1 definition excluded for brevity ...
},
"ep2": {
"endpointid": "ep2",
... remainder of ep2 definition excluded for brevity ...
}
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"ep1": {
"endpointid": "ep1",
... remainder of ep1 definition excluded for brevity ...
},
"ep2": {
"endpointid": "ep2",
... remainder of ep2 definition excluded for brevity ...
}
}
DELETE /<GROUPS> 🔗A server MAY support clients deleting one or more
Groups from a Group collection via an HTTP DELETE
directed to the Registry's <GROUPS> collection URL.
The processing of this API is defined in the Deleting Entities section of the core specification.
The request MUST be of the form:
DELETE /<GROUPS>
{
"<KEY>": { # <GROUP>id
"epoch": <UINTEGER> ?
} *
} ?
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 204 No Content
Examples:
Delete multiple Groups:
DELETE /endpoints
{
"ep1": {
"epoch": 5
},
"ep2": {}
}
HTTP/1.1 204 No Content
Notice that the epoch value for ep1 will be verified prior to the
delete, but no such check will happen for ep2.
GET /<GROUPS>/<GID> 🔗A server MAY support clients retrieving a
Group via an HTTP GET directed to the Group entity.
The request MUST be of the form:
GET /<GROUPS>/<GID>
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
... Group entity excluded for brevity ...
}
Examples:
Retrieve a single endpoints Group:
GET /endpoints/ep1
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"endpointid": "ep1",
"self": "https://example.com/endpoints/ep1",
"xid": "/endpoints/ep1",
"epoch": 1,
"name": "myEndpoint",
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"messagesurl": "https://example.com/endpoints/ep1/messages",
"messagescount": 5
}
PATCH and PUT /<GROUPS>/<GID> 🔗A server MAY support clients creating or updating a
Group in a Group collection via an HTTP PATCH or
PUT directed to the Group entity.
The processing of these APIs is defined in the Creating or Updating Entities section.
The request MUST be of the form:
PATCH /<GROUPS>/<GID>
Content-Type: application/json; charset=utf-8
or
PUT /<GROUPS>/<GID>
Content-Type: application/json; charset=utf-8
{ ... Group entity excluded for brevity ... }
The response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Group entity excluded for brevity ... }
Examples:
Create a new Endpoint:
PUT /endpoints/ep1
Content-Type: application/json; charset=utf-8
{
"endpointid": "ep1",
... remainder of Endpoint 'ep1' definition excluded for brevity ...
}
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Location: https://example.com/endpoints/ep1
{
"endpointid": "ep1",
... remainder of Endpoint 'ep1' definition excluded for brevity ...
}
POST /<GROUPS>/<GID> 🔗A server MAY support clients creating/updating one or more
Resources, of varying Resource types, within the
specified Group via an HTTP POST to the owning
Group.
The processing of this API is defined in the Creating or Updating
Entities section - see the discussion of the
POST <PATH-TO-ENTITY> variant.
A request that isn't a map of Resource types (e.g. it contains other Group level attributes) MUST generate an error (resources_only).
The request MUST be of the form:
POST /<GROUPS>/<GID>
Content-Type: application/json; charset=utf-8
{
"<RESOURCES>": {
"<KEY>": { # <RESOURCE>id
... Resource entity excluded for brevity ...
} *
} *
}
The response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"<RESOURCES>": {
"<KEY>": { # <RESOURCE>id
... Resource entity excluded for brevity ...
} *
} *
}
Examples:
Create a Message and a Schema Resource under Group g1:
POST /groups/g1
Content-Type: application/json; charset=utf-8
{
"messages": {
"messageid": "msg1",
... remainder of msg1 definition excluded for brevity ...
},
"schemas": {
"schemaid": "schema1",
... remainder of schema1 definition excluded for brevity ...
}
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"messages": {
"messageid": "msg1",
... remainder of msg1 definition excluded for brevity ...
},
"schemas": {
"schemaid": "schema1",
... remainder of schema1 definition excluded for brevity ...
}
}
DELETE /<GROUPS>/<GID> 🔗A server MAY support clients deleting a
Group via an HTTP DELETE directed to the Group
entity.
The processing of this API is defined in the Deleting Entities section of the core specification.
The request MUST be of the form:
DELETE /<GROUPS>/<GID>
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 204 No Content
Examples:
Delete a Group:
DELETE /endpoints/ep1
HTTP/1.1 204 No Content
Delete a Group, verifying its epoch value:
DELETE /endpoints/ep1?epoch=5
HTTP/1.1 204 No Content
The core specification's
Resource Metadata vs Resource Document
section explains how Resource types might be defined to have a
domain-specific document associated with them via their
hasdocument model aspect
being set to true. For HTTP, clients indicate whether they want to interact
with the Resource's xRegistry metadata or the Resource's domain-specific
document by the use of a $details suffix on the <RESOURCE>id in its URL.
Presence of the $details suffix MUST be interpreted as a request to interact
with the xRegistry metadata of the Resource, while its absence MUST be
interpreted as a request to interact with the Resource's domain-specific
document.
Inappropriate use of $details on an entity that does not support it MUST
generate an error (bad_details).
For example:
http://registry.example.com/schemagroups/mygroup/schemas/myschema$details
references the xRegistry metadata of the myschema Resource, while:
http://registry.example.com/schemagroups/mygroup/schemas/myschema
references the (domain-specific) schema document associated with the
myschema Resource.
If a Resource type does not support domain-specific documents (i.e.
hasdocument
is set to false), then use of the $details suffix in a request URL MUST
be treated the same as if it were absent and any URLs in server response
messages referencing that Resource (e.g. self) MUST NOT include it.
This section goes into more details concerning situations where a Resource
type is defined to support domain-specific documents (i.e.
hasdocument
is set to true.
When a Resource is serialized as its underlying domain-specific document,
in other words $details is not appended to its URL path, the HTTP body of
requests and responses MUST be the exact bytes of that document. If the
document is empty, then the HTTP body MUST be empty (zero length).
In this serialization mode, it might be useful for clients to also interact with some of the Resource's xRegistry metadata. To support this, some of the Resource's xRegistry metadata MAY appear as HTTP headers in messages.
On responses, unless otherwise stated, all top-level scalar attributes of the
Resource SHOULD appear as HTTP headers where the header name is the name of the
attribute prefixed with xRegistry-. Note, the optionality of this requirement
is not to allow for servers to decide whether or not to do so, rather it is to
allow for No-Code Servers servers that might not be
able to control the HTTP response headers.
The <RESOURCE> and <RESOURCEbase64> attributes MUST NOT be serialized as
HTTP headers, even if their values can be considered "scalar", because their
values will appear in the HTTP body.
Top-level map attributes whose values are of scalar types SHOULD also appear as
HTTP headers (each key having its own HTTP header) and in those cases the
HTTP header names will be of the form: xRegistry-<MAPNAME>.<KEYNAME>.
Note that map keys MAY contain the . character, so any . after the
<MAPNAME> is part of the key name. See
HTTP Header Values for additional information and
labels for an example of one such attribute.
Certain attributes do not follow this rule if a standard HTTP header name is defined for that semantic purpose. See the HTTP-Specific Attribute Processing Rules section for more information.
Complex top-level attributes (e.g. arrays, objects, non-scalar maps) MUST NOT appear as HTTP headers.
On update requests, similar serialization rules apply. However, rather than
these headers being REQUIRED, the client would only need to include those
top-level attributes that they would like to change. But, including unchanged
attributes MAY be done. Any attributes not included in request messages
MUST be interpreted as a request to leave their values unchanged. Using a
value of null (case-sensitive) MUST be processed as a request to delete that
attribute.
Any top-level map attributes that appear as HTTP headers MUST be included in their entirety and any missing keys MUST be interpreted as a request to delete those keys from the map.
Since only some types of attributes can appear as HTTP headers, in order
to manage the full set of attribute the xRegistry metadata view (via use
of the $details URL suffix) MUST be used instead.
When a Resource (not a Version) is serialized with the Resource document in the HTTP body, it MUST adhere to this form:
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING> # ID of Resource, not default Version
xRegistry-versionid: <STRING> # ID of the default Version
xRegistry-self: <URL> # Resource URL, not default Version
xRegistry-xid: <URI> # Relative Resource URI
xRegistry-epoch: <UINTEGER> # Start default Version's attributes
xRegistry-name: <STRING> ?
xRegistry-isdefault: true
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP>
xRegistry-modifiedat: <TIMESTAMP>
xRegistry-ancestor: <STRING>
xRegistry-<RESOURCE>url: <URL> ? # End of default Version attributes
xRegistry-metaurl: <URL> # Resource-level attributes
xRegistry-versionsurl: <URL>
xRegistry-versionscount: <UINTEGER>
Location: <URL> ?
Content-Location: <URL> ?
Content-Disposition: <STRING> ?
... Resource document excluded for brevity ... ?
Where:
<RESOURCE>id is the <SINGULAR>id of the Resource, not the default
Version.versionid attribute MUST be the ID of the Resource's default Version.xid URI references the Resource, not the default Version.versionsurl and versionscount Collection attributes are included,
but not the versions collection itself.Location header only appears in response to a create operation and
MUST be the same as the self URL.Content-Location header MAY appear, and if present, MUST reference
the "default" Version.Content-Disposition SHOULD be present and if so, MUST be the <RESOURCE>id
value. This allows for HTTP tooling that is not aware of xRegistry to know
the desired filename to use if the HTTP body were to be written to a file.Version serialization will look similar, but without the Resource-level attributes, and MUST be of the form:
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING> # ID of Resource, not default Version
xRegistry-versionid: <STRING> # ID of the default Version
xRegistry-self: <URL> # Version URL
xRegistry-xid: <URI> # Relative Version URI
xRegistry-epoch: <UINTEGER>
xRegistry-name: <STRING> ?
xRegistry-isdefault: <BOOLEAN>
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP>
xRegistry-modifiedat: <TIMESTAMP>
xRegistry-ancestor: <STRING>
xRegistry-<RESOURCE>url: <URL> ? # End of default Version attributes
Location: <URL> ?
Content-Location: <URL> ?
Content-Disposition: <STRING> ?
... Version document excluded for brevity ... ?
Where:
Content-Disposition SHOULD be present and if so, MUST be the <RESOURCE>id
value. This allows for HTTP tooling that is not aware of xRegistry to know
the desired filename to use if the HTTP body were to be written to a file.Scalar default Version extension attributes MUST also appear as
xRegistry- HTTP headers.
Notice that for Resources, the meta and versions attributes are not
included since they are complex data types.
Note: HTTP header values can be empty strings but some client-side tooling
might make it challenging to produce them. For example, curl requires
the header to be specified as -Hmyheader; - notice the semicolon(;) is
used instead of colon(:). So, this might be something to consider when
choosing to use attributes, or labels, that can be empty strings.
GET /<GROUPS>/<GID>/<RESOURCES> 🔗A server MAY support clients retrieving a
Resource collection from a
Group via an HTTP GET
directed to the owning Group's <RESOURCE> collection URL.
The request MUST be of the form:
GET /<GROUPS>/<GID>/<RESOURCES>
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Link: <URL>;rel=next;count=<UINTEGER> ?
{
"<KEY>": { # <RESOURCE>id
... Resource entity excluded for brevity ...
} *
}
Examples:
Retrieve all messages of an endpoint whose <GROUP>id is ep1:
GET /endpoints/ep1/messages
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Link: <https://example.com/endpoints/ep1/messages&page=2>;rel=next;count=100
{
"msg1": {
"messageid": "msg1",
"versionid": "1.0",
"self": "https://example.com/endpoints/ep1/messages/msg1",
"xid": "/endpoints/ep1/messages/msg1",
"epoch": 1,
"name": "Blob Created",
"isdefault": true,
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"ancestor": "1.0",
"metaurl": "https://example.com/endpoints/ep1/messages/msg1/meta",
"versionsurl": "https://example.com/endpoints/ep1/messages/msg1/versions",
"versionscount": 1
}
}
PATCH and POST /<GROUPS>/<GID>/<RESOURCES> 🔗A server MAY support clients creating/updating one or more
Resources within a
Group via an HTTP PATCH or
POST directed to the owning Group's <RESOURCE> collection URL.
The processing of these APIs is defined in the Creating or Updating
Entities section - see the discussion of the
POST/PATCH <PATH-TO-COLLECTION> variants.
The request MUST be of the form:
PATCH /<GROUPS>/<GID>/<RESOURCES>
Content-Type: application/json; charset=utf-8
or
POST /<GROUPS>/<GID>/<RESOURCES>
Content-Type: application/json; charset=utf-8
{
"<KEY>": { # <RESOURCE>id
... Resource entity excluded for brevity ...
} *
}
A successful response MUST be of the form:
HTTP/1.1 200 OK
{
"<KEY>": { # <RESOURCE>id
... Resource entity excluded for brevity ...
} *
}
Examples:
POST /endpoints/ep1/messages
Content-Type: application/json; charset=utf-8
{
"msg1": {
"endpointid": "msg1",
... remainder of msg1 definition excluded for brevity ...
},
"msg2": {
"endpointid": "msg2",
... remainder of msg2 definition excluded for brevity ...
}
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"msg1": {
"endpointid": "msg1",
... remainder of msg1 definition excluded for brevity ...
},
"msg2": {
"endpointid": "msg2",
... remainder of msg2 definition excluded for brevity ...
}
}
DELETE /<GROUPS>/<GID>/<RESOURCES> 🔗A server MAY support clients deleting one or more
Resources within a
Group via an HTTP DELETE directed to the owning
Group's <RESOURCE> collection URL.
The processing of this API is defined in the Deleting Entities section of the core specification.
The request MUST be of the form:
DELETE /<GROUPS>/<GID>/<RESOURCES>
{
"<KEY>": { # <RESOURCE>id
"epoch": <UINTEGER> ?
} *
} ?
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 204 No Content
Examples:
Delete multiple Resources:
DELETE /endpoints/ep1/messages
{
"msg1": {
"epoch": 5
},
"msg2": {}
}
HTTP/1.1 204 No Content
Notice that the epoch value for msg1 will be verified prior to the
delete, but no such check will happen for msg2.
GET /<GROUPS>/<GID>/<RESOURCES>/<RID> 🔗A server MAY support clients retrieving a
Resource within a
Group via an HTTP GET directed to the Resource
entity.
The request MUST be of the form:
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>[$details]
Where the $details suffix controls whether the request is directed to the
Resource metadata or to the Resource domain-specific document. See
Resource Metadata vs Resource Document
for more information.
When $details is used, or the Resource type is not configured to have a
domain-specific document, then a successful response MUST be:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Location: <URL> ?
{
... Resource entity excluded for brevity ...
}
Where:
Content-Location is present then it MUST be a URL to the Version of the
Resource in the versions collection - same as defaultversionurl.When $details is not used and the Resource type is configured to have a
domain-specific document, then a successful response MUST be either:
200 OK with the Resource document in the HTTP body.303 See Other with the location of the Resource's document being
returned in the HTTP Location header if the Resource has a <RESOURCE>url
value, and the HTTP body MUST be empty.For either response, the Resource's default Version attributes, along with the
meta and versions related scalar attributes, MUST be serialized as HTTP
xRegistry- headers.
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 303 See Other
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING>
xRegistry-versionid: <STRING>
xRegistry-self: <URL>
xRegistry-xid: <XID>
xRegistry-epoch: <UINTEGER>
xRegistry-name: <STRING> ?
xRegistry-isdefault: true
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP>
xRegistry-modifiedat: <TIMESTAMP>
xRegistry-ancestor: <STRING>
xRegistry-<RESOURCE>url: <URL> ? # If Resource is not in body
xRegistry-metaurl: <URL>
xRegistry-versionsurl: <URL>
xRegistry-versionscount: <UINTEGER>
Location: <URL> ? # If 303 is returned
Content-Location: <URL> ?
Content-Disposition: <STRING> ?
... Resource document ... # If <RESOURCE>url is not set
Where:
<RESOURCE>url is present then it MUST have the same value as Location.Content-Location is present then it MUST be a URL to the Version of the
Resource in the versions collection - same as defaultversionurl.Content-Disposition SHOULD be present and if so, MUST be the <RESOURCE>id
value. This allows for HTTP tooling that is not aware of xRegistry to know
the desired filename to use if the HTTP body were to be written to a file.Examples:
Retrieve a message Resource as xRegistry metadata:
GET /endpoints/ep1/messages/msg1$details
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Location: https://example.com/endpoints/ep1/messages/msg1/versions/1
{
"messageid": "msg1",
"versionid": "1",
"self": "https://example.com/endpoints/ep1/messages/msg1","
"xid": "/endpoints/ep1/messages/msg1",
"epoch": 1,
"name": "Blob Created",
"isdefault": true,
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"ancestor": "1",
"metaurl": "https://example.com/endpoints/ep1/messages/msg1/meta",
"versionsurl": "https://example.com/endpoints/ep1/messages/msg1/versions",
"versionscount": 1
}
PATCH and PUT /<GROUPS>/<GID>/<RESOURCES>/<RID> 🔗A server MAY support clients creating, or updating, a
Resource within a
Group via an HTTP PATCH or PUT directed to the
Resource entity.
The processing of these APIs is defined in the Creating or Updating Entities section.
The $details suffix controls whether the request is directed to the
Resource metadata or to the Resource domain-specific document. See
Resource Metadata vs Resource Document
for more information.
When directed to the Resource metadata, the request MUST be of the form:
PATCH /<GROUPS>/<GID>/<RESOURCES>/<RID>[$details]
Content-Type: application/json; charset=utf-8
or
PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>[$details]
Content-Type: application/json; charset=utf-8
{ ... Resource entity excluded for brevity ... }
The response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Resource entity excluded for brevity ... }
When directed to the Resource's domain-specific document, the request MUST be of the form:
PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>
Content-Type: application/json; charset=utf-8
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING> ?
xRegistry-versionid: <STRING> ? # Version-level attributes
xRegistry-epoch: <UINTEGER> ?
xRegistry-name: <STRING> ?
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP> ?
xRegistry-modifiedat: <TIMESTAMP> ?
xRegistry-ancestor: <STRING> ?
xRegistry-<RESOURCE>url: <URL> ?
... Resource document excluded for brevity ... ?
Note that PATCH for Resources with domain-specific documents is not
supported.
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 201 Created
or
HTTP/1.1 303 See Other
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING>
xRegistry-versionid: <STRING>
xRegistry-self: <URL>
xRegistry-xid: <XID>
xRegistry-epoch: <UINTEGER>
xRegistry-name: <STRING> ?
xRegistry-isdefault: true
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP>
xRegistry-modifiedat: <TIMESTAMP>
xRegistry-ancestor: <STRING>
xRegistry-<RESOURCE>url: <URL> ? # If Resource is not in body
xRegistry-metaurl: <URL>
xRegistry-versionsurl: <URL>
xRegistry-versionscount: <UINTEGER>
Location: <URL> ? # If 201 or 303 is returned
Content-Location: <URL> ?
Content-Disposition: <STRING> ?
... Resource document ... # If <RESOURCE>url is not set
Where:
Content-Disposition SHOULD be present and if so, MUST be the <RESOURCE>id
value. This allows for HTTP tooling that is not aware of xRegistry to know
the desired filename to use if the HTTP body were to be written to a file.Examples:
Create a new Resource:
PUT /endpoints/ep1/messages/msg1
Content-Type: application/json; charset=utf-8
xRegistry-name: Blob Created
{ ... Definition of "Blob Created" event (document) excluded for brevity ... }
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
xRegistry-messageid: msg1
xRegistry-versionid: 1
xRegistry-self: https://example.com/endpoints/ep1/messages/msg1
xRegistry-xid: /endpoints/ep1/messages/msg1
xRegistry-epoch: 1
xRegistry-name: Blob Created
xRegistry-isdefault: true
xRegistry-ancestor: 1
xRegistry-metaurl: https://example.com/endpoints/ep1/messages/msg1/meta
xRegistry-versionsurl: https://example.com/endpoints/ep1/messages/msg1/versions
xRegistry-versionscount: 1
Location: https://example.com/endpoints/ep1/messages/msg1
Content-Location: https://example.com/endpoints/ep1/messages/msg1/versions/1
Content-Disposition: msg1
{ ... Definition of "Blob Created" event (document) excluded for brevity ... }
Update the default Version of a Resource as xRegistry metadata:
PUT /endpoints/ep1/messages/msg1$details
Content-Type: application/json; charset=utf-8
{
"epoch": 1,
"name": "Blob Created",
"description": "a cool event",
"message": {
# Updated definition of a "Blob Created" event excluded for brevity
}
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Location: https://example.com/endpoints/ep1/messages/msg1/versions/1
{
"messageid": "msg1",
"versionid": "1",
"self": "https://example.com/endpoints/ep1/messages/msg1",
"xid": "/endpoints/ep1/messages/msg1",
"epoch": 2,
"name": "Blob Created",
"isdefault": true,
"description": "a cool event",
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"ancestor": "1",
"message": {
# Updated definition of a "Blob Created" event excluded for brevity
},
"metaurl": "https://example.com/endpoints/ep1/messages/msg1/meta",
"versionsurl": "https://example.com/endpoints/ep1/messages/msg1/versions",
"versionscount": 1
}
POST /<GROUPS>/<GID>/<RESOURCES>/<RID> 🔗A server MAY support clients creating, or updating, a single
Version of a
Resource via an HTTP POST directed to the
Resource entity.
The processing of this API is defined in the Creating or Updating Entities section.
The $details suffix controls whether the request is directed to the
Version metadata or to the Version domain-specific document. See
Resource Metadata vs Resource Document
for more information.
When directed to the metadata of the entity, the request MUST be of the form:
POST /<GROUPS>/<GID>/<RESOURCES>/<RID>[$details]
Content-Type: application/json; charset=utf-8
{ ... Version entity excluded for brevity ... }
The response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Version entity excluded for brevity ... }
When directed to the entity's domain-specific document, the request MUST be of the form:
POST /<GROUPS>/<GID>/<RESOURCES>/<RID>
Content-Type: application/json; charset=utf-8
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING> ?
xRegistry-versionid: <STRING> ? # Version-level attributes
xRegistry-epoch: <UINTEGER> ?
xRegistry-name: <STRING> ?
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP> ?
xRegistry-modifiedat: <TIMESTAMP> ?
xRegistry-ancestor: <STRING> ?
xRegistry-<RESOURCE>url: <URL> ?
... Version document excluded for brevity ... ?
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 201 Created
or
HTTP/1.1 303 See Other
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING>
xRegistry-versionid: <STRING>
xRegistry-self: <URL>
xRegistry-xid: <XID>
xRegistry-epoch: <UINTEGER>
xRegistry-name: <STRING> ?
xRegistry-isdefault: <BOOLEAN>
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP>
xRegistry-modifiedat: <TIMESTAMP>
xRegistry-ancestor: <STRING>
xRegistry-<RESOURCE>url: <URL> ? # If Resource is not in body
Location: <URL> ? # If 201 or 303 is returned
Content-Location: <URL> ?
Content-Disposition: <STRING> ?
... Version document excluded for brevity ... # If <RESOURCE>url is not set
Where:
Content-Disposition SHOULD be present and if so, MUST be the <RESOURCE>id
value. This allows for HTTP tooling that is not aware of xRegistry to know
the desired filename to use if the HTTP body were to be written to a file.Examples:
Create a new Version:
POST /endpoints/ep1/messages/msg1
Content-Type: application/json; charset=utf-8
xRegistry-name: Blob Created
{ ... Definition of "Blob Created" event (document) excluded for brevity ... }
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
xRegistry-messageid: msg1
xRegistry-versionid: 2
xRegistry-self: https://example.com/endpoints/ep1/messages/msg1/versions/2
xRegistry-xid: /endpoints/ep1/messages/msg1/versions/2
xRegistry-epoch: 1
xRegistry-name: Blob Created
xRegistry-isdefault: true
xRegistry-ancestor: 1
Location: https://example.com/endpoints/ep1/messages/msg1/versions/v2
Content-Location: https://example.com/endpoints/ep1/messages/msg1/versions/2
Content-Disposition: msg1
{ ... Definition of "Blob Created" event (document) excluded for brevity ... }
Update a Version of a Resource as xRegistry metadata:
POST /endpoints/ep1/messages/msg1$details
Content-Type: application/json; charset=utf-8
{
"epoch": 1,
"name": "Blob Created",
"description": "a cool event",
"message": {
# Updated definition of a "Blob Created" event excluded for brevity
}
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Location: https://example.com/endpoints/ep1/messages/msg1/versions/1
{
"messageid": "msg1",
"versionid": "1",
"self": "https://example.com/endpoints/ep1/messages/msg1/versions/1",
"xid": "/endpoints/ep1/messages/msg1",
"epoch": 2,
"name": "Blob Created",
"isdefault": true,
"description": "a cool event",
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"ancestor": "1",
"message": {
# Updated definition of a "Blob Created" event excluded for brevity
},
}
DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID> 🔗A server MAY support clients deleting a
Resource via an HTTP DELETE directed
to the Resource entity.
The processing of this API is defined in the Deleting Entities section of the core specification.
The request MUST be of the form:
DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 204 No Content
Examples:
Delete a Resource:
DELETE /endpoints/ep1/messages/msg1
HTTP/1.1 204 No Content
Delete a Resource, verifying its epoch value:
DELETE /endpoints/ep1/messages/msg1?epoch=5
HTTP/1.1 204 No Content
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>/meta 🔗A server MAY support clients retrieving a
Resource's Meta entity via an HTTP GET directed
to the Resource's Meta entity.
The request MUST be of the form:
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>/meta
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ .. Meta entity excluded for brevity ... }
Examples:
Retrieve a Resource's Meta entity:
GET /endpoints/ep1/messages/msg1/meta
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"messageid": "msg1",
"self": "https://example.com/endpoints/ep1/messages/msg1/meta",
"xid": "/endpoints/ep1/messages/msg1/meta",
"epoch": 2,
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"compatibility": "none",
"defaultversionid": "v2.0",
"defaultversionurl": "https://example.com/endpoints/ep1/messages/msg1/versions/v2.0",
"defaultversionsticky": false
}
PATCH and PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>/meta 🔗A server MAY support clients updating a
Resource's Meta entity via an HTTP PATCH or
PUT directed to the Resource's Meta entity.
The processing of these APIs is defined in the Creating or Updating Entities section.
The request MUST be of the form:
PATCH /<GROUPS>/<GID>/<RESOURCES>/<RID>/meta
Content-Type: application/json; charset=utf-8
or
PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>/meta
Content-Type: application/json; charset=utf-8
{ ... Meta entity excluded for brevity ... }
The response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Meta entity excluded for brevity ... }
Examples:
Update a Resource's defaultversionid attribute:
PATCH /endpoints/ep1/messages/msg1/meta
Content-Type: application/json; charset=utf-8
{
"defaultversionid": "v2.0"
}
HTTP/1.1 200 Created
Content-Type: application/json; charset=utf-8
{
"messageid": "msg1",
"self": "https://example.com/endpoints/ep1/messages/msg1/meta",
"xid": "/endpoints/ep1/messages/msg1/meta",
"epoch": 2,
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"compatibility": "none",
"defaultversionid": "v2.0",
"defaultversionurl": "https://example.com/endpoints/ep1/messages/msg1/versions/v2.0",
"defaultversionsticky": false
}
DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/meta 🔗A DELETE directed to the Meta entity is not supported and MUST generate an
error (action_not_supported).
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions 🔗A server MAY support clients retrieving the
versions collection of a
Resource via an HTTP GET directed to the
owning Resource's versions collection URL.
The request MUST be of the form:
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Link: <URL>;rel=next;count=<UINTEGER> ?
{
"<KEY>": { # The versionid
... Version entity excluded for brevity ...
} *
}
Examples:
Retrieve all Version of a message Resource:
GET /endpoints/ep1/messages/msg1/versions
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Link: <https://example.com/endpoints/ep1/messages/msg1/versions&page=2>;rel=next;count=100
{
"1.0": {
"messageid": "msg1",
"versionid": "1.0",
"self": "https://example.com/endpoints/ep1/messages/msg1",
"xid": "/endpoints/ep1/messages/msg1",
"epoch": 1,
"name": "Blob Created",
"isdefault": true,
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"ancestor": "1.0"
}
}
PATCH and POST /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions 🔗A server MAY support clients creating/updating one or more
Versions, of a
Resource via an HTTP PATCH or POST directed
to the owning Resource's
versions collection URL.
The processing of these APIs is defined in the Creating or Updating
Entities section - see the discussion of the
POST/PATCH <PATH-TO-COLLECTION> variants.
The request MUST be of the form:
PATCH /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions
Content-Type: application/json; charset=utf-8
or
POST /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions
Content-Type: application/json; charset=utf-8
{
"<KEY>": { # <GROUP>id
... Version entity excluded for brevity ...
} *
}
The response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"<KEY>": { # <GROUP>id
... Version entity excluded for brevity ...
} *
}
Examples:
Update several Versions (adding a label):
PATCH /endpoints/ep1/messages/msg1/versions
Content-Type: application/json; charset=utf-8
{
"1": {
"labels": { "customer": "abc" },
},
"2": {
"labels": { "customer": "abc" },
},
"3": {
"labels": { "customer": "abc" },
}
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"1": {
"messageid": "msg1",
"versionid": "1",
"labels": { "customer": "abc" },
# Remainder of Version entity excluded for brevity
},
"2": {
"messageid": "msg1",
"versionid": "2",
"labels": { "customer": "abc" },
# Remainder of Version entity excluded for brevity
},
"3": {
"messageid": "msg1",
"versionid": "3",
"labels": { "customer": "abc" },
# Remainder of Version entity excluded for brevity
}
]
Note that in this case, the new "label" replaces all existing labels, it is not a "merge" operation because all attributes need to be specified in their entirety.
DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions 🔗A server MAY support clients deleting one or more
Versions within a specified
Resource via an HTTP DELETE directed to the
owning Resource's versions collection URL.
The processing of this API is defined in the Deleting Entities section of the core specification.
The request MUST be of the form:
DELETE /<GROUPS>/<GID>/<RESOURCES>/versions
{
"<KEY>": { # versionid
"epoch": <UINTEGER> ?
} *
} ?
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 204 No Content
Examples:
Delete multiple Versions:
DELETE /endpoints/ep1/messages/msg1/versions
{
"v1.0": {
"epoch": 5
},
"v2.0": {}
}
HTTP/1.1 204 No Content
Notice that the epoch value for v1.0 will be verified prior to the
delete, but no such check will happen for v2.0.
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID> 🔗A server MAY support clients retrieving a
Version of a
Resource via an HTTP GET directed to the
Version entity.
The request MUST be of the form:
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>[$details]
Where the $details suffix controls whether the request is directed to the
Version metadata or to the Version domain-specific document. See
Resource Metadata vs Resource Document
for more information.
When $details is used, or the Resource is not configured to have a
domain-specific document, then a successful response MUST be of the form:
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
... Version entity excluded for brevity ...
}
When $details is not used and the Resource is configured to have a
domain-specific document, then a successful response MUST either return the
Version's domain-specific document, or an HTTP redirect to
the <RESOURCE>url value if set.
In the case of returning the Version's domain-specific document, the response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.2 303 See Other
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING>
xRegistry-versionid: <STRING>
xRegistry-self: <URL>
xRegistry-xid: <XID>
xRegistry-epoch: <UINTEGER>
xRegistry-name: <STRING> ?
xRegistry-isdefault: <BOOLEAN>
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP>
xRegistry-modifiedat: <TIMESTAMP>
xRegistry-ancestor: <STRING>
Location: <URL> ? # If 303 is returned
Content-Disposition: <STRING> ?
... Version document ... # If <RESOURCE>url is not set
Where:
Content-Disposition SHOULD be present and if so, MUST be the <RESOURCE>id
value. This allows for HTTP tooling that is not aware of xRegistry to know
the desired filename to use if the HTTP body were to be written to a file.Location, if present, and <RESOURCE>url MUST have the same value.Examples:
Retrieve a specific Version of a schema Resource as xRegistry metadata:
GET /schemagroups/g1/schemas/myschema/versions/1.0$details
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"schemaid": "myschema",
"versionid": "1.0",
"self": "https://example.com/schemagroups/g1/schemas/myschema/versions/1.0",
"xid": "/endpoints/ep1/messages/msg1/versions/1.0",
"epoch": 2,
"isdefault": true,
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"ancestor": "1.0"
}
Retrieve the domain-specific document of the same schema Resource:
GET /schemagroups/g1/schemas/myschema/versions/1.0
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
xRegistry-schemaid: myschema
xRegistry-versionid: 1.0
xRegistry-self: https://example.com/schemagroups/g1/schemas/myschema/versions/1.0
xRegistry-xid: /schemagroups/g1/schemas/myschema/versions/1.0
xRegistry-epoch: 2
xRegistry-isdefault: true
xRegistry-createdat: 2024-04-30T12:00:00Z
xRegistry-modifiedat: 2024-04-30T12:00:01Z
xRegistry-ancestor: 1.0
Content-Disposition: myschema
{ ... Contents of a schema doc excluded for brevity ... }
PATCH and PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID> 🔗A server MAY support clients creating or updating a
Version of a
Resource via an HTTP PATCH or PUT directed
to the Version.
The processing of these APIs is defined in the Creating or Updating Entities section.
The $details suffix controls whether the request is directed to the
Resource metadata or to the Resource domain-specific document. See
Resource Metadata vs Resource Document
for more information.
When directed to the Version metadata, the request MUST be of the form:
PATCH /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>[$details]
Content-Type: application/json; charset=utf-8
or
PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>[$details]
Content-Type: application/json; charset=utf-8
{ ... Version entity excluded for brevity ... }
The response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{ ... Version entity excluded for brevity ... }
When directed to the Version's domain-specific document, the request MUST be of the form:
PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>
Content-Type: application/json; charset=utf-8
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING> ?
xRegistry-versionid: <STRING> ? # Version-level attributes
xRegistry-epoch: <UINTEGER> ?
xRegistry-name: <STRING> ?
xRegistry-isdefault: <BOOLEAN>
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP> ?
xRegistry-modifiedat: <TIMESTAMP> ?
xRegistry-ancestor: <STRING> ?
xRegistry-<RESOURCE>url: <URL> ?
... Version document excluded for brevity ... ?
Note that PATCH for Resources with domain-specific documents is not
supported.
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 201 Created
or
HTTP/1.1 303 See Other
Content-Type: <STRING> ?
xRegistry-<RESOURCE>id: <STRING>
xRegistry-versionid: <STRING>
xRegistry-self: <URL>
xRegistry-xid: <XID>
xRegistry-epoch: <UINTEGER>
xRegistry-name: <STRING> ?
xRegistry-isdefault: <BOOLEAN>
xRegistry-description: <STRING> ?
xRegistry-documentation: <URL> ?
xRegistry-icon: <URL> ?
xRegistry-labels.<KEY>: <STRING> *
xRegistry-createdat: <TIMESTAMP>
xRegistry-modifiedat: <TIMESTAMP>
xRegistry-ancestor: <STRING>
xRegistry-<RESOURCE>url: <URL> ? # If Resource is not in body
Location: <URL> ? # If 201 or 303 is returned
Content-Location: <URL> ?
Content-Disposition: <STRING> ?
... Version document ... # If <RESOURCE>url is not set
Examples:
Create a new Version:
PUT /endpoints/ep1/messages/msg1/versions/v2.0
Content-Type: application/json; charset=utf-8
xRegistry-name: Blob Created v2
{ ... Definition of "Blob Created" event (document) excluded for brevity ... }
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
xRegistry-messageid: msg1
xRegistry-versionid: v2.0
xRegistry-self: https://example.com/endpoints/ep1/messages/msg1/versions/v2.0
xRegistry-xid: /endpoints/ep1/messages/msg1/versions/v2.0
xRegistry-epoch: 1
xRegistry-name: Blob Created v2
xRegistry-isdefault: true
xRegistry-ancestor: v1.0
Location: https://example.com/endpoints/ep1/messages/msg1/versions/v2.0
Content-Location: https://example.com/endpoints/ep1/messages/msg1/versions/v2.0
Content-Disposition: msg1
{ ... Definition of "Blob Created" event (document) excluded for brevity ... }
Update a Version of a Resource as metadata:
PUT /endpoints/ep1/messages/msg1/versions/v2.0$details/
Content-Type: application/json; charset=utf-8
{
"name": "Blob Created v2",
"description": "a cool event",
"message": {
# Updated definition of a "Blob Created" event excluded for brevity
},
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Location: https://example.com/endpoints/ep1/messages/msg1/versions/v2.0
{
"messageid": "msg1",
"versionid": "1",
"self": "https://example.com/endpoints/ep1/messages/msg1/versions/v2.0",
"xid": "/endpoints/ep1/messages/msg1/versions/v2.0",
"epoch": 2,
"name": "Blob Created v2",
"isdefault": true,
"description": "a cool event",
"createdat": "2024-04-30T12:00:00Z",
"modifiedat": "2024-04-30T12:00:01Z",
"ancestor": "v1.0",
"message": {
# Updated definition of a "Blob Created" event excluded for brevity
},
}
DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID> 🔗A server MAY support clients deleting a
Version of a
Resource via an HTTP DELETE directed to the
Version entity.
The processing of this API is defined in the Deleting Entities section of the core specification.
The request MUST be of the form:
DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>
A successful response MUST be of the form:
HTTP/1.1 200 OK
or
HTTP/1.1 204 No Content
Examples:
Delete a Version:
DELETE /endpoints/ep1/messages/msg1/versions/1.0
HTTP/1.1 204 No Content
Delete a Resource, verifying its epoch value:
DELETE /endpoints/ep1/messages/msg1/versions?epoch=5
HTTP/1.1 204 No Content
The core xRegistry specification defines a set of request flags that MAY be used to control the processing of requests as well as influence how response messages are generated. Each flag is mapped to an HTTP query parameter per the following rules:
?FLAG_NAME, all lower case.?FLAG_NAME=VALUE, where the FLAG_NAME MUST be all
lower case. The flag MUST NOT be specified more than once.There are exceptions to these rules as specified by the following:
?filter Flag 🔗A server MAY support the ?filter query parameter allowing clients to reduce
the response entities to just the ones that match certain criteria.
See Filter Flag for more information.
This query parameter MUST be serialized as:
?filter=<EXPRESSION>[,...]*
Where:
<EXPRESSION> values within the scope of one ?filter query parameter
MUST be evaluated as a logical AND per the
core specification.?filter query parameter MAY appear multiple times and if so MUST
be evaluated as a logical OR with the other ?filter query parameters that
appear - per the core specification.The abstract processing logic would be:
?filter query parameter, find all entities that satisfy all
<EXPRESSION> for that ?filter. Each will result in a sub-tree of entities.?filter query parameters, combine those
sub-trees into one result set and remove any duplicates - adjusting any
collection url and count values as needed.?ignore Flag 🔗A server MAY support the ?ignore query parameter on any write operation
to indicate that certain aspects of the request message MUST be ignored
by the server).
See Ignore Flag for more information.
This query parameter MUST be serialized as:
?ignore[=<value>[,...]*]
Where:
<value> indicate which aspect of the request message to ignore.* is an alias for all server supported values.*.?ignore query parameter MAY be specified more than once.?inline Flag 🔗A server MAY support the ?inline query parameter on any request to indicate
which nested collections/objects, or potentially large attributes, are to be
included in the response message.
See Inline Flag for more information.
This query parameter MUST be serialized as:
?inline[=<PATH>[,...]*]
Where:
<PATH> is as defined in Inline Flag.?inline query parameter MAY Include a single
<PATH> value or be a comma-separated list of <PATH> values.?inline query parameter MAY be specified more than once.?sort Flag 🔗A server MAY support the ?sort query parameter on any request directed to
a collection of Groups, Resources or Versions.
See Sort Flag for more information.
This query parameter MUST be serialized as:
?sort=<ATTRIBUTE>[=asc|desc]
Some attributes can contain arbitrary UTF-8 string content, and per RFC7230, section 3, HTTP headers MUST only use printable characters from the US-ASCII character set, and are terminated by a CRLF sequence with OPTIONAL whitespace around the header value.
When encoding an attribute's value as an HTTP header, it MUST be percent-encoded as described below. This is compatible with [RFC3986, section 2.1][rfc3986-section-2-1] but is more specific about what needs encoding. The resulting string SHOULD NOT be further encoded. (Rationale: quoted string escaping is unnecessary when every space and double-quote character is already percent-encoded.)
When decoding an HTTP header into an attribute's value, any HTTP header value MUST first be unescaped with respect to double-quoted strings, as described in RFC7230, section 3.2.6. A single round of percent-decoding MUST then be performed as described below. HTTP headers for attribute values do not support parenthetical comments, so the initial unescaping only needs to handle double-quoted values, including processing backslash escapes within double-quoted values. Header values produced via the percent-encoding described here will never include double-quoted values, but they MUST be supported when receiving events, for compatibility with older versions of this specification which did not require double-quote and space characters to be percent-encoded.
Percent encoding is performed by considering each Unicode character within the attribute's canonical string representation. Any character represented in memory as a [Unicode surrogate pair][surrogate-pair] MUST be treated as a single Unicode character. The following characters MUST be percent-encoded:
Space and double-quote are encoded to avoid requiring any further quoting. Percent is encoded to avoid ambiguity with percent-encoding itself.
Steps to encode a Unicode character:
%xy where x is a
hexadecimal representation of the most significant 4 bits of the byte,
and y is a hexadecimal representation of the least significant 4
bits of the byte.Percent-encoding SHOULD be performed using upper-case for values A-F, but decoding MUST accept lowercase values.
When performing percent-decoding, values that have been unnecessarily percent-encoded MUST be accepted, but encoded byte sequences which are invalid in UTF-8 MUST generate an error (header_error). For example, "%C0%A0" is an overlong encoding of U+0020, and would be rejected.
Example: a header value of "Euro € 😀" SHOULD be encoded as follows:
When an error is transmitted back to clients, it SHOULD adhere to the format specified in this section - which references the Problem Details for HTTP APIs specification, and when used, MUST be of the following form:
HTTP/1.1 <CODE>
Content-Type: application/json; charset=utf-8
{
"type": "<URI>",
"title": "<STRING>",
"detail": "<STRING>", ?
"subject": "<STRING>", ?
"args": {
"<STRING>": "<STRING>", * // arg name -> arg value
}, ?
"instance": "<URL>", ?
"source": "<STRING>", ?
... extension error fields ...
}
See the Error Processing section in the core specification for more information.
The following list of HTTP protocol specific errors are defined:
https://github.com/xregistry/spec/blob/main/core/http.md#details_required405 Method Not Allowed$details suffix is needed when using PATCH for the entity: <subject>.<resource_xid>https://github.com/xregistry/spec/blob/main/core/http.md#extra_xregistry_header400 Bad RequestxRegistry HTTP header "<name>" is not allowed on this request: <error_detail>.<request_path>name: The invalid xRegistry HTTP header name.error_detail: Specific details about the error.https://github.com/xregistry/spec/blob/main/core/http.md#header_error400 Bad RequestThere was an error processing HTTP header "<name>": <error_detail>.name: The HTTP header name.https://github.com/xregistry/spec/blob/main/core/http.md#missing_body400 Bad RequestThe request is missing an HTTP body - try '{}'.<request_path>