zachaysan
zachaysan

Reputation: 1826

JSON API self vs related links for relationships URLs

What is the difference between what is at the self link and the related link for JSON API?

Upvotes: 1

Views: 681

Answers (1)

zachaysan
zachaysan

Reputation: 1826

I was have so much trouble finding a straightforward, readable answer to what I actually return on the response.

For the example at JSON API they have the following JSON:

{
  "links": {
    "self": "http://example.com/articles",
    "next": "http://example.com/articles?page[offset]=2",
    "last": "http://example.com/articles?page[offset]=10"
  },
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!"
    },
    "relationships": {
      "author": {
        "links": {
          "self": "http://example.com/articles/1/relationships/author",
          "related": "http://example.com/articles/1/author"
        },
        "data": { "type": "people", "id": "9" }
      },
      "comments": {
        "links": {
          "self": "http://example.com/articles/1/relationships/comments",
          "related": "http://example.com/articles/1/comments"
        },
        "data": [
          { "type": "comments", "id": "5" },
          { "type": "comments", "id": "12" }
        ]
      }
    },
    "links": {
      "self": "http://example.com/articles/1"
    }
  }],
  "included": [{
    "type": "people",
    "id": "9",
    "attributes": {
      "first-name": "Dan",
      "last-name": "Gebhardt",
      "twitter": "dgeb"
    },
    "links": {
      "self": "http://example.com/people/9"
    }
  }, {
    "type": "comments",
    "id": "5",
    "attributes": {
      "body": "First!"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "2" }
      }
    },
    "links": {
      "self": "http://example.com/comments/5"
    }
  }, {
    "type": "comments",
    "id": "12",
    "attributes": {
      "body": "I like XML better"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "9" }
      }
    },
    "links": {
      "self": "http://example.com/comments/12"
    }
  }]
}

This line here:

"self": "http://example.com/articles/1/relationships/author"

Is a "relationship link"

This line here:

"self": "http://example.com/articles/1/relationships/comments"

Is also a "relationship link"

Yeah, I know it is confusing, since the other one is called related. What is the purpose of these links? The purpose is only manage the relationships. So say you do a GET /articles/1/relationships/comments you do not return the comments' information. You only return an array of resource types / ids and some other stuff, like meta data and links. Example:

{ 
  "data": [{
    "type": "comments",
    "id": "13" 
  }, {
    "type": "comments",
    "id": "29" 
  }],
  "links": {
    "self": "http://example.com/articles/1/relationships/comments",
    "next": "http://example.com/articles/1/relationships/comments?page[offset]=2",
    "last": "http://example.com/articles/1/relationships/comments?page[offset]=4"
  },
  "meta": {
    "copyright": "Copyright 2015 Example Corp.",
    "authors": [
      "Zach Aysan"
    ]}
}

Why is this useful? Because sometimes we want to just delete the relationship, not the resource (comment, author) itself. So for example if we did a DELETE /articles/1/relationships/author that wouldn't delete the user from the users table, it would just remove that user as an author. To delete only some comments, we do a PATCH /articles/1/relationships/comments and only include the comments we want to keep. Keep in mind, however, that the backend may delete the actual comments if it thinks that's the right thing to do. (Since what good are comments without an associated article?)

What about the other link? Why is it /articles/1/author instead of /people/9? Because the author of an article may change between requests and GET /articles/1/author will always return the current author. This is why we usually don't need to support things like PATCH /articles/1/author because it usually makes more sense / is safer to direct the change at the resource itself. PATCH /people/9, if, for example someone changes their avatar while on the edit articles page. Even if an admin changed the authorship of the article that PATCH still went to the correct resource.

I know. It's all a bit tedious, but once everything is understood things like Ember Data should just snap together.

Upvotes: 3

Related Questions