HATEOAS Navigation Controls¶
To comply with REST architectural principles without polluting the core domain JSON models, the Resource Registry API implements Hypermedia as the Engine of Application State (HATEOAS) exclusively at the protocol level. It leverages the standard HTTP Link header (RFC 8288) using official IANA Link Relation Types.
This decouples the navigation logic from the structural representation of the instances. Clients can dynamically discover related resources, schemas, and pagination bounds by reading the response headers.
Endpoint Relation Matrix¶
The following table explicitly maps the HATEOAS link relations emitted by the various API endpoints.
Surface-preserving links: Every link target stays on the surface the request entered through. The table shows the management paths; when the request arrives through the /access facade, every emitted target is the corresponding path under /access (for example parent points to /access/contexts/{parent-uuid} and type to /access/types/{type-name}). A client that follows links from an /access response never leaves the facade.
| Endpoint Group | API Path | Emitted Relations (rel) |
Target URI Meaning |
|---|---|---|---|
| Collections (Paginated) | GET /contextsGET /instances/{type}GET /query-templates |
nextprevfirst |
Points to the respective paginated slice of the collection using limit and offset query parameters. |
| Execute Query (Paginated) | QUERY /contextsQUERY /typesQUERY /instancesQUERY /query-templatesQUERY /query-templates/{name} |
nextprevfirst |
Points to the respective paginated slice of the query results using limit and offset query parameters. The client repeats the same request against the link target (see Following Pagination Links of a Query). |
| Context Read | GET /contexts/{uuid} |
parentcollection |
parent: Points to the parent Context (/contexts/{parent-uuid}); not emitted for the Root Context, which has no parent.collection: Points to the base context collection (/contexts). |
| Context Create / Tracked Update | PUT /contexts/{uuid}PATCH /contexts/{uuid} |
parentcollection |
Same as Context Read, for the created or updated Context. |
| Read Current | GET /contexts/@current |
parentcollection |
Same as Context Read: parent points to the parent Context (/contexts/{parent-uuid}); collection points to the base context collection (/contexts). |
| Context History | GET /contexts/{uuid}/history |
up |
up: Points back to the Context that owns this history (/contexts/{uuid}). |
| Type Read | GET /types/{type-name} |
supertype |
supertype: Points to the direct parent Type schemas served by GET /types/{type-name}. Emits multiple links if multiple inheritance is used. |
| Instance Read | GET /instances/{type}/{uuid} |
typecollection |
type: Points to the canonical schema definition (/types/{type-name}).collection: Points to the base instance collection (/instances/{type}). |
| Instance Contexts | GET /instances/{type}/{uuid}/contexts |
up |
up: Points back to the HTTP resource that owns this mapping (/instances/{type}/{uuid}). |
| Query Template Read | GET /query-templates/{name} |
collection |
collection: Points to the base query templates collection (/query-templates). |
Architectural & Semantic Notes¶
Following Pagination Links of a Query¶
A QUERY request carries its query in the body, which a link target cannot express. A pagination link of a query endpoint is therefore followed by repeating the same request against the link target: same method, same headers, same body; only the URI changes. The link target keeps the form of the request that produced it: a native QUERY {path} receives links on {path}, while the POST {path}/query fallback receives links on {path}/query. This holds for collection queries and for the execution of a stored Query Template alike, whose variable-substitution body is repeated unchanged.
The Deliberate Omission of rel="last"¶
In the paginated collection endpoints, the API intentionally emits first, next, and prev, but strictly omits the last relation.
Rationale: Calculating the absolute last page of a dataset requires the underlying graph database to perform a full COUNT(*) over the query results. In highly dynamic or massive datasets, calculating the total count often incurs a severe performance penalty that exceeds the cost of fetching the page itself. Clients are expected to simply follow next links until the header no longer provides one.
Semantic Resolution of up, parent, and supertype¶
The official IANA definition for up is "a parent document in a hierarchy of documents". To prevent cognitive dissonance between URL hierarchies, logical business containment, and object-oriented inheritance, the API deliberately splits this concept into three precise relations:
rel="parent"(Pragmatic Deviation): For Contexts, the API uses the explicitly unregistered relationparentto point to the logical parent Context (/contexts/{parent-uuid}). While RFC 8288 dictates the use of absolute URIs for unregistered extension relations to avoid future IANA collisions, the API makes a conscious Pragmatic Deviation by using the simple stringparentto maximize Developer Experience and readability.rel="supertype"(Pragmatic Deviation): For Schema Types, the API emitssupertypeto point to the immediate parent classes (as defined in theextendedTypesarray). If a Type uses multiple inheritance, the API legitimately returns multiplesupertypelinks. This perfectly matches thesupertypesnomenclature used in the JSON payload. A link is emitted for every declared parent that is served as a Type definition,EntityandRelationincluded. The namesPropertyElement,EntityElement, andRelationElement, which appear in theextendedTypesof the topmost definitions, are not served as Type definitions and therefore receive no link.rel="up"(Standard URL Hierarchy): When querying a sub-resource mapping likeList Instance ContextsorRead History, theuprelation acts strictly as a URL breadcrumb, pointing the client back "up" the REST path to the parentHTTP resourcethat owns the sub-collection.
Schema Discovery via rel="type"¶
The Open-World paradigm relies on self-describing schemas. When a client reads a graph instance, the server emits Link: </types/{type-name}>; rel="type". This provides a standard programmatic affordance for generic clients or UI renderers to proactively discover and fetch the JSON blueprint required to validate or display the payload, without needing to hardcode the registry paths.
Header Syntax for Multiple Links¶
When an endpoint emits multiple relations (e.g., pagination controls, or multiple supertype links for multiple inheritance), the server emits multiple individual Link headers. However, in accordance with HTTP semantics, intermediate proxies may fold them into a single comma-separated string. Clients must be prepared to parse either format.
Example 1: Pagination (e.g., retrieving the second page of a list)
Link: </contexts?limit=50&offset=100>; rel="next"
Link: </contexts?limit=50&offset=0>; rel="prev"
Link: </contexts?limit=50&offset=0>; rel="first"
Example 2: Multiple Inheritance
(Note: While the gcube-model currently does not utilize multiple inheritance, the Information System natively supports it. The following is a fictitious example of a Type extending both HostingNode and EService).