xRegistry HTTP Binding
August 19, 2026 · View on GitHub
Abstract
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.
Table of Contents
- Notations and Terminology
- HTTP Binding Overview
- Registry HTTP APIs
- Entity Processing Rules
- Registry Entity
- Registry Capabilities
- Registry Model
- Group Entity
- Resource Entity
- Meta Entity
- Version Entity
GET /<GROUPS>/<GID>/<RESOURCES>/<RID>/versionsPATCHandPOST /<GROUPS>/<GID>/<RESOURCES>/<RID>/versionsDELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/versionsGET /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>PATCHandPUT /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>
- xRegistry Discovery
- Request Flags / Query Parameters
- HTTP Header Values
- Error Processing
Notations and Terminology
Notational Conventions
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 attributes 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 resulting 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.
Terminology
See the core specification for the list of xRegistry defined terms that might be used.
HTTP Binding Overview
HTTP API Patterns
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:
- New HTTP paths that extend non-root paths MUST NOT be defined as they might conflict with URLs of entities within the system.
- New root HTTP paths MAY be defined as long as they do not use Registry-level HTTP paths or attribute names. This includes extension and Groups collection attribute names.
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.
Adherence to HTTP Standards
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:
- A
PUTorPOSToperation 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. - A
PATCHoperation MUST only modify the attributes explicitly mentioned in the request. Any attribute in the request with a value ofnullMUST be interpreted as a request to delete the attribute, and as withPUT/POST, server-managed attributes might have specialized processing. PUTMUST NOT be targeted at xRegistry collections. APOSTorPATCHMUST be used instead to add entities to the collection, and aDELETEMUST then be used to delete unwanted entities.- Unknown query parameters SHOULD be silently ignored by servers. This includes specification-defined but unsupported query parameters.
- Despite the
HTTP specification
saying that the
PUTmethod is idempotent, this specification does not adhere to that rule when it comes to theepochandmodifiedatattributes. While multiple identicalPUTrequests will yield the same semantic effect as a singlePUTfor all other attributes, theepochandmodifiedatattributes are designed to always be updated on each write operation to that entity.
No-Code Servers
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
as 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.
Registry HTTP APIs
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.
Entity Processing Rules
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.
Creating or Updating Entities
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 entities
See 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:
- The URL MUST be of the form:
<PATH-TO-ENTITY>. - The HTTP body MUST contain the full updated serialization of the entity to be processed.
- The entity processed MUST either be created (if it does not already exist), or updated (if it does exist).
- Any mutable attribute which is either missing or present with a value of
null, MUST be interpreted as a request to delete the attribute. - Excluding any Registry collection attributes, all mutable attributes specified MUST be a full serialization of the attribute. Any missing nested attribute MUST be interpreted as a request to delete the attribute.
- After processing the request, if there are any missing REQUIRED attributes then an error (required_attribute_missing) MUST be generated.
The PATCH variant when directed at a single entity, MUST adhere to the PUT
semantics defined above with the following exceptions:
- Any mutable attribute which is missing MUST be interpreted as a request to
leave it unchanged. However, modifying some other attribute (or some other
server semantics) MAY modify it. A value of
nullMUST be interpreted as a request to delete the attribute. - When processing a Resource or Version, whose Resource type has its
hasdocumentmodel aspect set totrue, the URL accessing the entity MUST include the$detailssuffix, and MUST generate an error (details_required) in the absence of the$detailssuffix. This is because when it is absent, the processing of the HTTPxRegistry-headers are already defined with "PATCH" semantics so a normalPUTorPOSTcan be used instead. UsingPATCHin this case would mean that the request is trying to "patch" the Resource's "document", which this specification does not support at this time. PATCHMAY 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:
- The HTTP body MUST contain only a JSON map where the key MUST be the
attribute (collection) name of a nested xRegistry collection. The value
of each map entry MUST be a map of nested entities where the key is the
entity's
<SINGULAR>idand the value is a serialization of the entity itself. - The processing of each top-level map entry MUST follow the same rules
as defined for
POSTto the nested xRegistry collection where the map entry's value is the input. - The root of the JSON object in the HTTP body MUST NOT contain any attributes of the targeted entity other than the nested collections, and none of that entity's attribute are to be updated. This operation allows for an update to multiple nested collections in a single operation without modifying the owning entity.
- The response message MUST be a map of the nested entity types with just the changed entities that were processed. No top-level entity attributes are to appear - similar to the request message.
The POST variant when directed at a Resource entity, MUST adhere to the
following:
- The HTTP body MUST contain the serialization of the single Version to be
created, however, it MAY include Resource-level read-only attributes (such
as
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 attributes would be included in the serialization. - The 'PUT' variant rules above MUST apply to the new Version entity.
The PATCH variant when directed at an xRegistry collection, MUST adhere to
the following:
- The HTTP body MUST contain a JSON map where the key MUST be the
<SINGULAR>idof each entity in the map. Note, that in the case of a map of Versions, theversionidis used. - Each value in the map MUST contain just the attributes that are to be updated for that entity.
- The processing of each individual entity in the map MUST follow the same
rules as defined for
PATCHof a single entity above.
The POST variant when directed at an xRegistry collection MUST adhere to the
following:
- The HTTP body MUST contain a JSON map where the key MUST be the
<SINGULAR>idof each entity in the map. Note, that in the case of a map of Versions, theversionidis used. - Each value in the map MUST be the full serialization of the entity to be
either added or updated. Note that
POSTdoes not support deleting entities from a collection, so a separate delete operation might be needed if there are entities that need to be removed. - The processing of each individual entity in the map MUST follow the same
rules as defined for
PUTabove. - In the case of an empty map of Versions and the Resource being referenced
does not exist yet, an error (missing_versions) MUST
be generated because a Resource can not exist without any Versions. If
the intent was to create a Resource with a Version that has just default
values, then there are other APIs that can be used that make that intent
clear (e.g.
PUTto the Resource itself).
The processing of each individual entity follows the same set of rules:
- If an entity with the specified
<SINGULAR>idalready 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. - See the definition of each attribute for the rules governing how it is processed.
- Unless otherwise noted, all non-xRegistry collection attributes present MUST be a full representation of their values. This means any complex attributes (e.g. objects, maps), MUST be fully replaced by the incoming value.
- A request to update, or delete, a read-only attribute MUST be silently
ignored. However, a request that includes a
<SINGULAR>idMUST be compared with the entity's current value and if it differs then an error (mismatched_id) MUST be generated. This includes both<RESOURCE>idandversionidin the case of Resources and Versions. This is to prevent accidentally updating the wrong entity. - A request to update a mutable attribute with an invalid value MUST generate an error (invalid_attribute) (this includes deleting a mandatory mutable attribute that has no default value defined).
- Registry collection attributes MUST be processed per the rules specified in the Updating Nested Registry Collections section.
- Write operations that are meant to include xRegistry metadata in the HTTP
body MUST NOT be empty, and if detected MUST generate an error
(missing_body). To denote an empty set of
metadata,
{}MUST be used instead. - Any error during the processing of an entity, or its nested entities, MUST result in the entire request being rejected and no updates performed.
Resources and Versions have the following additional rules:
- When a write operation request includes the Resource/Version's metadata in
the HTTP body, then the inclusion of any xRegistry
xRegistry-HTTP headers MUST generate an error (extra_xregistry_header). - When a write operation request includes a domain-specific document in the
HTTP body, and the
<RESOURCE>urlxRegistry HTTP header is present with a non-null value, the HTTP body MUST be empty. If the<RESOURCE>urlattribute is absent, then the contents of the HTTP body (even if empty) are to be used as the entity's document. - The
<RESOURCE>and<RESOURCEbase64>attributes MUST never appear as xRegistry HTTP headers, and if present on a 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:
- In the
POSTcase, or aPATCHdirected to an xRegistry collection, the result MUST contain only the entities processed, not the entire Registry collection. - In the
PUTorPATCHcases that are directed to a single entity, for a newly created entity, the HTTP status MUST be201 Created, and it MUST include an HTTPLocationheader with a URL to the newly created entity. Note that this URL MUST be the same as theselfattribute of that entity. - In the
PUTorPATCHcases directed at a single Resource or Version, if a new Version was created, the response MUST include aContent-LocationHTTP header to the newly created Version entity, and it MUST be the same as the Version'sselfattribute. - The responses MUST NOT include any inlineable attributes (such as
<RESOURCE>,<RESOURCE>base64or 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).
xRegistry Root HTTP Header
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
HTTP-Specific Attribute Processing Rules
self Attribute
In addition to the core specification's definition of
self, the following HTTP-specific rules apply:
- When serializing Resources and Versions, whose Resource type's
hasdocumentaspect is set totrue, then this URL MUST include the$detailssuffix appended to its<SINGULAR>idif it is serialized in the the HTTP body response. If the aspect is set tofalsethen 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:
- When
labelsis 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 ofxRegistry-labels.<KEYNAME>.
contenttype Attribute
In addition to the core specification's definition of
contenttype, the following HTTP-specific
rules apply:
- When this attribute is serialized as an HTTP header, it MUST use the name
Content-Typeand notxRegistry-contenttype. - On an update request when the xRegistry metadata appears in HTTP headers,
unlike other attributes that will remain unchanged when not specified,
this attribute MUST be erased if the incoming request does not include
the
Content-TypeHTTP header.
<RESOURCE> Attribute
In addition to the core specification's definition of
<RESOURCE>, 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.
<RESOURCE>base64 Attribute
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.
Pagination
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 that the pagination specification
MAY be used for that API.
HTTP OPTIONS Method
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.- The same
<METHODS>values MUST be returned for both headers. OPTIONSMUST be one of the values returned.- This operation MUST NOT modify any data within the Registry.
- Implementations MAY choose to include other information per the RFC9110 specification.
Examples:
Retrieve the supported list of HTTP methods at the root of the Registry:
OPTIONS /
HTTP/1.1 200 OK
Allow: GET, OPTIONS
Access-Control-Allow-Methods: GET, OPTIONS
Registry Entity
GET /
A server MAY support clients retrieving the
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-rc4",
"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:
- With the exception of the
capabilities,modelsourceand Groups attributes, the HTTP body MUST contain the full representation of the Registry entity in the case ofPUT, or the full representation of just the modified attributes in the case ofPATCH. - A missing
capabilitiesormodelsourceattribute MUST NOT result in any changes to those values. - For both the
PATCHandPUTcases, if present, themodelsourceattribute MUST be a complete replacement representation of the model definition. A value ofnullor{}MUST reset the model to the server's default value (no Groups, Resources, extension attributes or custom specification-defined attributes). See Creating or Updating the Registry Model for more information. - When the
capabilitiesattribute is present andPATCHis used then only the top-level capabilities specified in the request MUST be updated. But, each capability present MUST be specified in its entirety. WhenPUTis used then it MUST be a complete replacement definition of all the capabilities. In either case, a value ofnullMUST 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-rc4",
"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>": {
"<GROUP>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).
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"<GROUPS>": {
"<GROUP>id": {
... Group entity excluded for brevity ...
} *
} *
}
Where:
- The response MUST only include the Groups that were processed, and not any Registry-level attributes.
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:
- As a shorthand convenience syntax for clients that need to download the entire Registry as a single document. For example, to then be used in an "import" type of operation for another Registry, or for tooling that does not need the duplication of information that Doc Flag removes.
- Note, the semantics of the
docandinlineflags MUST still be adhered to even if explicitly specifying those flags is not supported by the server. - To allow for servers that do not support query parameters (such as No-Code Servers) to expose the entire Registry with a single (non-query parameterized) API call.
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 ...
}
Registry Capabilities
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
{
"available": [
"/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-rc4" ]
}
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
{
"available": {
"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-rc4" ]
},
"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:
- The HTTP body MUST contain the full representation of all capabilities
in the case of
PUT, or the full representation of just the modified capabilities in the case ofPATCH.
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: 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
}
{
"available": [
"/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-rc4" ]
}
Registry Model
GET /model
A server MUST support clients retrieving its full
model definition via an HTTP GET directed to
the stand-alone 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, if supported.
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.
In cases where the Registry's model has never been specified via modelsource,
this operation MUST return {} not an empty HTTP body.
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, if
supported.
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.
Note: the HTTP body MUST be a JSON object and an empty request MUST generate
an error (missing_body). To denote an empty model, {} SHOULD
be used instead.
Group Entity
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 ... }
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:
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 ...
} *
} *
}
A successful 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
Resource Entity
Resource Metadata vs Resource Document
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.
Use of $details on a non-Resource entity 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.
Serializing Resource Domain-Specific Documents
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 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. Unless otherwise stated, 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 attributes, 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-ancestorid: <STRING>
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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:
- The
<RESOURCE>idis the<SINGULAR>idof the Resource, not the default Version. - The
versionidattribute MUST be the ID of the Resource's default Version. - The
xidURI references the Resource, not the default Version. - The
versionsurlandversionscountCollection attributes are included, but not theversionscollection itself. - The
Locationheader only appears in response to a create operation and MUST be the same as theselfURL. - The
Content-Locationheader MAY appear, and if present, MUST reference the "default" Version. Content-DispositionSHOULD be present and if so, MUST be the<RESOURCE>idvalue. 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-ancestorid: <STRING>
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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-DispositionSHOULD be present and if so, MUST be the<RESOURCE>idvalue. 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",
"ancestorid": "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:
- If
Content-Locationis present then it MUST be a URL to the Version of the Resource in theversionscollection - same asmeta.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 OKwith the Resource document in the HTTP body.303 See Otherwith the location of the Resource's document being returned in the HTTPLocationheader if the Resource has a<RESOURCE>urlvalue, 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-ancestorid: <STRING>
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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:
- If
<RESOURCE>urlis present then it MUST have the same value asLocation. - If
Content-Locationis present then it MUST be a URL to the Version of the Resource in theversionscollection - same asmeta.defaultversionurl. Content-DispositionSHOULD be present and if so, MUST be the<RESOURCE>idvalue. 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",
"ancestorid": "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 ... }
A successful 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: <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-ancestorid: <STRING> ?
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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-ancestorid: <STRING>
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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-DispositionSHOULD be present and if so, MUST be the<RESOURCE>idvalue. 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-ancestorid: 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",
"ancestorid": "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 the versionid attribute is absent in the request then a new Version
MUST be created. When present, then the server MUST update the specified
Version rather than create a new one. If the specified Version does not
already exist then a new Version MUST be created.
When directed to the metadata of the Resource, 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 ... }
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 directed to the Resource's domain-specific document, the request MUST be of the form:
POST /<GROUPS>/<GID>/<RESOURCES>/<RID>
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-ancestorid: <STRING> ?
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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-ancestorid: <STRING>
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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-DispositionSHOULD be present and if so, MUST be the<RESOURCE>idvalue. 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-ancestorid: 1
Location: https://example.com/endpoints/ep1/messages/msg1/versions/2
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
{
"versionid": "1",
"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",
"ancestorid": "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
Meta Entity
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 ... }
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:
Update a Resource's defaultversionid attribute:
PATCH /endpoints/ep1/messages/msg1/meta
Content-Type: application/json; charset=utf-8
{
"defaultversionid": "v1.0"
}
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": "v1.0",
"defaultversionurl": "https://example.com/endpoints/ep1/messages/msg1/versions/v1.0",
"defaultversionsticky": true
}
DELETE /<GROUPS>/<GID>/<RESOURCES>/<RID>/meta
A DELETE directed to the Meta entity is not supported and MUST generate an
error (action_not_supported).
Version Entity
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 Versions 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",
"ancestorid": "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 ...
} *
}
A successful 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:
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.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-ancestorid: <STRING>
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <STRING> ?
Location: <URL> ? # If 303 is returned
Content-Disposition: <STRING> ?
... Version document ... # If <RESOURCE>url is not set
Where:
Content-DispositionSHOULD be present and if so, MUST be the<RESOURCE>idvalue. 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>urlMUST 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",
"ancestorid": "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-ancestorid: 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 ... }
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 directed to the Version's domain-specific document, the request MUST be of the form:
PUT /<GROUPS>/<GID>/<RESOURCES>/<RID>/versions/<VID>
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-ancestorid: <STRING> ?
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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-ancestorid: <STRING>
xRegistry-format: <STRING> ?
xRegistry-formatvalidated: <BOOLEAN> ?
xRegistry-formatvalidatedreason: <STRING> ?
xRegistry-compatibilityvalidated: <BOOLEAN> ?
xRegistry-compatibilityvalidatedreason: <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-ancestorid: 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",
"ancestorid": "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
xRegistry Discovery
As defined by the core specification, clients
MAY query an xRegistry server for the list of additional xRegistry servers
that might be of interest. If supported, the Registry-based discovery file,
for an HTTP server, MUST be available at the root of the Registry (e.g. as a
sibling API to /model) via the /.xregistry API:
GET /.xregistry
A successful response MUST be of the form:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"registries": {
"URL", *
}
}
Note that unlike the Host-based Discovery
mechanism, this API includes a dot (.) before xregistry to avoid any
potential name collisions with the xRegistry's data.
Request Flags / Query Parameters
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:
- When the flag is a boolean type of flag then it MUST be serialized
as
?FLAG_NAME, all lower case. - When the flag has a single value associated with it, then it MUST be
serialized as
?FLAG_NAME=VALUE, where theFLAG_NAMEMUST be all lower case. The flag MUST NOT be specified more than once. - When the flag allows for multiple values, then each value MUST be serialized as a separate query parameter per the previous bullets.
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:
- All
<EXPRESSION>values within the scope of one?filterquery parameter MUST be evaluated as a logicalANDper the core specification. - The
?filterquery parameter MAY appear multiple times and if so MUST be evaluated as a logicalORwith the other?filterquery parameters that appear - per the core specification.
The abstract processing logic would be:
- For each
?filterquery parameter, find all entities that satisfy all<EXPRESSION>values for that?filter. Each will result in a sub-tree of entities. - After processing all individual
?filterquery parameters, combine those sub-trees into one result set and remove any duplicates - adjusting any collectionurlandcountvalues 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>indicates which aspect of the request message to ignore.- A value of
*is an alias for all server supported values. - No value, or an empty string, is an alias for
*. - The
?ignorequery 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.- The value portion of the
?inlinequery parameter MAY Include a single<PATH>value or be a comma-separated list of<PATH>values. - The
?inlinequery 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]
HTTP Header Values
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 (U+0020).
- Double-quote (U+0022).
- Percent (U+0025).
- Any characters outside the printable ASCII range of U+0021-U+007E inclusive.
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:
- Encode the character using UTF-8, to obtain a byte sequence.
- Encode each byte within the sequence as
%xywherexis a hexadecimal representation of the most significant 4 bits of the byte, andyis 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:
- The characters, 'E', 'u', 'r', 'o' do not require encoding.
- Space, the Euro symbol, and the grinning face emoji require encoding. They are characters U+0020, U+20AC and U+1F600 respectively.
- The encoded HTTP header value is therefore "Euro%20%E2%82%AC%20%F0%9F%98%80" where "%20" is the encoded form of space, "%E2%82%AC" is the encoded form of the Euro symbol, and "%F0%9F%98%80" is the encoded form of the grinning face emoji.
Error Processing
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:
api_not_found
- Type:
https://github.com/xregistry/spec/blob/main/core/http.md#api_not_found - Code:
404 Not Found - Title:
The specified API is not supported: <subject>. - Subject:
<request_path>
request_path MUST be the "Path" portion of the incoming request URL,
starting with /. E.g. /export if the "export" feature is not supported.
details_required
- Type:
https://github.com/xregistry/spec/blob/main/core/http.md#details_required - Code:
405 Method Not Allowed - Title:
$details suffix is needed when using PATCH for the entity: <subject>. - Subject:
<resource_xid>
extra_xregistry_header
- Type:
https://github.com/xregistry/spec/blob/main/core/http.md#extra_xregistry_header - Code:
400 Bad Request - Title:
For "<subject>", xRegistry HTTP header "<name>" is not allowed on this request: <error_detail>. - Subject:
<request_path> - Args:
name: The invalid xRegistry HTTP header name.error_detail: Specific details about the error.
header_error
- Type:
https://github.com/xregistry/spec/blob/main/core/http.md#header_error - Code:
400 Bad Request - Title:
For "<subject>", there was an error processing HTTP header "<name>": <error_detail>. - Subject:
<request_path> - Args:
name: The HTTP header name.
missing_body
- Type:
https://github.com/xregistry/spec/blob/main/core/http.md#missing_body - Code:
400 Bad Request - Title:
For "<subject>", the request is missing an HTTP body - try '{}'. - Subject:
<request_path>
missing_versions
- Type:
https://github.com/xregistry/spec/blob/main/core/http.md#missing_versions - Code:
400 Bad Request - Title:
For "<subject>", at least one Version needs to be included in the request. - Subject:
<request_path>