Is it ok to add multiple levels of nested relationships in the relationships field

Hi,

I have an API with the following urls:
/session
/session/account
/session/account/profile

I was wondering if it is ok to include both /session/account and /session/account/profile as relationships of the /session, like this:

// GET `/session` response
{
    "links": {
        "self": "https://example.com/session"
    },
    "data": {
        "id": "sessionid123",
        "type": "session"
        "relationships": {
            "account": {
                "links": {
                    "related": "https://example.com/session/account"
                },
                "data": {
                    "id": "abc1234",
                    "type": "account"
                }
            },
            "profile": {
                "links": {
                    "related": "https://example.com/session/account/profile"
                },
                "data": {
                    "id": "profileid",
                    "type": "accountProfile"
                }
            }
        }
    }
}

or if the /session/account/profile relationship is only a relationship of /session/account (that is, it should be in the relationships field only when requesting /session/account).

Thanks!

This is allowed, but it might not be the right way to go. The issue is that doing it this way will make a client think that there are two distinct "profile" relationships: one that’s part of the sessionid123 session resource and a different one that’s part of the abc1234 account resource. Representing this as two distinct relationships might mean, for example, that the client wouldn’t know to keep those two relationships in sync locally.

So, another option would be to include the related account on the GET /session request, and then the included account will link to the profile. That approach would look like this:

GET /session

{
  "links": {
    "self": "https://example.com/session"
  },
  "data": {
    "id": "sessionid123",
    "type": "session",
      "relationships": { 
        "account": {
          "links": {
            "related": "https://example.com/session/account"
          },
          "data": {"id": "abc1234", "type": "account"}
        }
     }
  },
  // We're including the related account, even though
  // the user didn't explicitly add a `?include=account`
  // to the URI. JSON API allows this for convenience.
  "included": [{
    "id": "abc1234",
    "type": "account",
    "attributes": {
       /* fields of the included account. If the user
         doesn't care about this data, they can add
         `?fields[account]=profile` to the URI to just 
         get the profile. */
     },
    "relationships": {
      "profile": {
        "links": {
          "related": "https://example.com/account/abc1234/profile"
        },
        "data": {
          "id": "profileid",
          "type": "accountProfile"
        } 
    }
  }]
}

With this second approach, you’re more clearly representing that a session points to an account and an account points to a profile, but you’re still exposing the profile information to the user upfront when they make their request for the session.

That said, the choice is up to you. If, for instance, having the included key bothers you more than the duplicated relationship, the other approach is allowed, as I mentioned.

1 Like