Search code examples
urinaming-conventionsjson-api

Many-to-Many JSON API URI naming


I'm wondering if the following naming convention would correctly fit the JSON API standard, as it is not specifically mentioned anywhere that I can find.

Given a many to many relationship between accounts and products, with an account-product resource storing pivot data between the two.

I would to know how to handle the /api/v1/accounts/1/products relationship resource

account > account-product > product

URLs:

/api/v1/accounts: returns account resources

/api/v1/account-products: returns account-product resources

/api/v1/accounts/1/products: returns account-product resources

OR

/api/v1/accounts/1/products: return product resources related to the account


The two arguments here being this:

Option 1: account/1/products should return the link between the accounts and the products as it should essentially act as the ID should essentially act as a hyphen e.g. account/1/products really means account-products.

Option 2: account/1/products should returns products related to the account and also include the account-products resource as a mandatory relationship because the resource in the URI is product, not account-product


Solution

  • JSON:API specification is agnostic about URL design. Therefore it mostly depends where these URLs are used. But JSON:API spec comes with some recommendations on URL design. I assume that you follow that ones. Especially that /api/v1/accounts/1/products is used as related resource link, e.g.

    {
      "type": "accouts",
      "id": "1",
      "relationships": {
        "products": {
          "links": {
            "related": "/api/v1/accounts/1/products"
          }
        }
      }
    }
    

    In that case the spec is quite clear about what should be returned:

    Related Resource Links

    A “related resource link” provides access to resource objects linked in a relationship. When fetched, the related resource object(s) are returned as the response’s primary data.

    For example, an article’s comments relationship could specify a link that returns a collection of comment resource objects when retrieved through a GET request.

    https://jsonapi.org/format/#document-resource-object-related-resource-links

    From how you describe your data structure an account has many account-products, which belongs to a product. So it should return the related account-products. You may include the products they belong to by default.

    What may confuse you is the concept of intermediate relations like "Has One Through" in some ORMs (e.g. Eloquent). The naming account-products suggest that this might be an example of such. Something like that is not supported by JSON:API spec. Intermediate relationships should modeled using a normal resource type. So in your case account-products would be a normal resource type like accounts and products.