Spec for /articles/1/author URLs

There is no dedicated section for URLs that look like /articles/1/author, but references to it are scattered around the spec.

How this is used?

The JSON:API specification does not cover URL structure, and it shouldn’t. Knowing appropriate “starter” URLs is left for the documentation of specific APIs.

My understanding has been that this is intentional, and that seems like the best way to deal with the issue to me; it does not make sense to bake in assumptions about implementation strategy (such as a relational database) that might impact the URLs used. In all cases, an application can use the starter URLs documented for the API, and the URLs handed to it via the API.

One approach I like for minimizing the set of specific starter URLs is to define an “api-root” type that includes attributes and relationship to any collections that an application would need; only the URL to the “api-root” resource would need to be specified in the documentation, and the remaining URLs can change or evolve as needed over the lifetime of the service.

-Fred

1 Like

Hi @fdrake,

My question is since the /articles/1/author is mentioned in the spec (along with other URL examples), what does it represent?

The /articles/1/relationships/author endpoint represents article’s to-one relationship to author. Also, Fetching Relationships explains pretty well the expected output of a relationships endpoint.

But what is /articles/1/author?

Okay, I think I understand what you’re asking now.

I can explain this in the context of the example URL system used in the spec, but keep in mind that URLs should not generally be constructed in the client; it’s always best to use the URLs provided by the service.

If the resource at /articles/1 has an author relationship, that relationship’s links can contain two distinct URLs:

  • self is a link to the relationship itself, and in the example URL scheme, would be /articles/1/relationships/author, as you noted.

  • related is a link to the related resource. For a relationship that can’t be modified, it could be a “canonical” URL to the resource (e.g., /people/2), but for a relationship that can be modified, the URL needs to be specific to the /articles/1 resource. So, /articles/1/author is the resource at the other end of the author relationship.

    The important semantic here is that the URL provided as links.related for the relationship refers to whatever resource is referenced by the relationship, even if it changes before it is requested.

Consider that you request /articles/1 without ?include=author; you might expect only to get the relationship structure:

{"data": {
     "type": "article",
     "id": "1",
     "relationships": {
         "author": {
             "type": "person",
             "id": "2",
             "links": {
                 "related": "/articles/1/author",
                 "self": "/articles/1/relationships/author"
             }
         },
         ...},
 }}

If another client changes the author relationship to refer to a different resource, using the links.related URL will return the resource currently referenced by the updated /articles/1, which will not correlate to the resource identification originally returned with the resource. (Which suggests the resource identification data for a relationship probably should not be included if the resource is not also included in the response.)

I hope this helps!

-Fred

2 Likes

@fdrake thank you for the explanation.

It looks that while related resources in form of /articles/1/author could be useful in some cases, the spec has very small amount of information about them, especially what should happen if someone runs CRUD operations on such resources.

I’m not sure what you think needs to be said. Those example URLs address resources, and CRUD operations against resources are described.

Any limitations regarding CRUD operations on particular resources are in the domain of the application, and need not be associated with the URL used to access them.

-Fred