How should I indicate hateoas links in a catalog endpoints?

36 Views Asked by At

We are trying to start using HATEOAS in some our APIs but we are having some doubts how to write the links in the responses. So we have this endpoint, that return a list of resources. We are having some doubts about the names using in rel. We have two opinions on the team:

  1. The rel inside each resource should be called self.
{
  "items": [
    { "id": 1, "_links": { "rel": "self", "href": "host/resources/1"} },
    { "id": 2, "_links": { "rel": "self", "href": "host/resources/2"} },
    ...
  ],
  "_links": { "rel": "self", "href": "host/resources"}
}
  1. The rel inside each resource should be called details.
{
  "items": [
    { "id": 1, "_links": { "rel": "details", "href": "host/resources/1"} },
    { "id": 2, "_links": { "rel": "details", "href": "host/resources/2"} },
    ...
  ],
  "_links": { "rel": "self", "href": "host/resources"}
}

The reasoning behidn option two is that self indicates the same url you use to obtain that response, and technically that would have to be host/resources. On the other hand, people going for option 1 suggest that using self has to point to the endpoint to get the object where the _links property is.

Maybe we are just overcomplicating this, not sure. What do you think would be a correct approach? Is there a standard of something about common HATEOAS naming/structure?

1

There are 1 best solutions below

0
VoiceOfUnreason On

The currently registered reference for the "self" relation is RFC 4287.

The value "self" signifies that the IRI in the value of the href attribute identifies a resource equivalent to the containing element.

Expressed in terms of Web Linking, "self" indicates that the link target is the preferred URI for the link context. (The expectation being that if an explicit context isn't specified, then there are some rules for how to determine the implicit context - in the case of the web, that normally means the context is the web page you are looking at).

Having a self target that does not match the identifier used to obtain the resource is fine, but not necessarily common.


"details" appears to be an error -- as of 2023-04-06, there is no [registered reference] for a details relation. That means you are dealing with an extension relation, and you probably don't want to be using implicit reference resolution in that case; extension relations are identified by URI, so you should probably make it look like one

{ "rel": "https://example.org/link-relations/details", "href": "host/resources/2"}

Note: the extension relation type should be a URI (RFC 3986), but doesn't necessarily have to be an HTTP URI.


You may want to also consider the implications that you are (in general) permitted to specify more than one relation type that targets a single URI

Link </B>; rel="self https://example.org/link-relations/details"

So if you decide that details means something different from self, and you want to communicate both relations to a client, you can do that (exact details of doing so depend on the production rules for your representation).