# 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](https://datatracker.ietf.org/doc/html/rfc8288)) using official [IANA Link Relation Types](https://www.iana.org/assignments/link-relations/link-relations.xhtml).

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.

| Endpoint Group | API Path | Emitted Relations (`rel`) | Target URI Meaning |
|----------------|----------|---------------------------|--------------------|
| **Collections (Paginated)** | `GET /contexts`<br>`GET /instances/{type}`<br>`GET /query-templates` | `next`<br>`prev`<br>`first` | Points to the respective paginated slice of the collection using `limit` and `offset` query parameters. |
| **Execute Query (Paginated)** | `QUERY /contexts`<br>`QUERY /types`<br>`QUERY /instances`<br>`QUERY /query-templates`<br>`QUERY /query-templates/{name}` | `next`<br>`prev`<br>`first` | Points to the respective paginated slice of the query results using `limit` and `offset` query parameters. |
| **Context Read** | `GET /contexts/{uuid}` | `parent`<br>`collection` | `parent`: Points to the parent Context (`/contexts/{parent-uuid}`).<br>`collection`: Points to the base context collection (`/contexts`). |
| **Read Current** | `GET /contexts/@current`<br>`GET /access/contexts/@current` | `parent`<br>`collection` | 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}` | `type`<br>`collection` | `type`: Points to the canonical schema definition (`/types/{type-name}`).<br>`collection`: Points to the base instance collection (`/instances/{type}`). |
| **Instance Contexts** | `GET /instances/{type}/{uuid}/contexts`<br>`GET /access/instances/{type}/{uuid}/contexts` | `up` | `up`: Points back to the `HTTP resource` that owns this mapping, preserving the core or Access facade prefix. |
| **Query Template Read** | `GET /query-templates/{name}` | `collection` | `collection`: Points to the base query templates collection (`/query-templates`). |

## Architectural & Semantic Notes

### 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 relation `parent` to 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 string `parent` to maximize Developer Experience and readability.
- **`rel="supertype"` (Pragmatic Deviation):** For Schema Types, the API emits `supertype` to point to the immediate parent classes (as defined in the `extendedTypes` array). If a Type uses multiple inheritance, the API legitimately returns multiple `supertype` links. This perfectly matches the `supertypes` nomenclature used in the JSON payload. The links cover the parents served as Type definitions, `Entity` and `Relation` among them. `PropertyElement`, `EntityElement` and `RelationElement` organize the Type hierarchy and appear among the declared parents in `extendedTypes`.
- **`rel="up"` (Standard URL Hierarchy):** When querying a sub-resource mapping like `List Instance Contexts` or `Read History`, the `up` relation acts strictly as a URL breadcrumb, pointing the client back "up" the REST path to the parent `HTTP resource` that 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)*
```http
Link: </contexts?limit=50&offset=50>; 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`).*
```http
Link: </types/HostingNode>; rel="supertype"
Link: </types/EService>; rel="supertype"
```
