laravel-json-api / laravel

JSON:API for Laravel applications
MIT License
553 stars 42 forks source link

Allow adding links to Relationship Object #166

Open LeeJump24 opened 2 years ago

LeeJump24 commented 2 years ago

Is it possible to add a link to a relationship? So add a link to the firstQuestion

"relationships": {
  "questions": {
    "links": {
      "firstQuestion": "http://localhost/api/v1/questions/616c98f8-3ea9-4bb2-8152-3dd40c3846eb",
      "related": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3/questions",
      "self": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3/relationships/questions"
    }
  }
}

I'm not an expert on the spec but reading https://jsonapi.org/format/#document-resource-object-relationships sounds like it should be allowed? We can add extra links to other link objects.

Full example

{
  "jsonapi": {
    "version": "1.0"
  },
  "links": {
    "self": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3"
  },
  "data": {
    "type": "surveys",
    "id": "4b732db9-48da-43c9-bec0-6df2dc7dcbe3",
    "attributes": {
      "name": "Survey A",
      "description": "Description of Survey A"
    },
    "relationships": {
      "questions": {
        "links": {
          "firstQuestion": "http://localhost/api/v1/questions/616c98f8-3ea9-4bb2-8152-3dd40c3846eb",
          "related": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3/questions",
          "self": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3/relationships/questions"
        }
      }
    },
    "links": {
      "self": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3"
    }
  }
}
lindyhopchris commented 2 years ago

Thanks for opening this issue, definitely something I need to add.

lindyhopchris commented 1 year ago

So there's an upcoming clarification in the JSON:API spec, that the links object is only meant for use for JSON:API links. See this PR: https://github.com/json-api/json-api/pull/1691

If that gets merged and tagged, this issue will need to close - as adding links to a relationship object would go against the spec.

ben221199 commented 1 year ago

Seems to me that it is possible to define extension links, but I don't know for sure. Example:

{
    "links": {
        "myExtension:someLink": "https://example.com"
    }
}
lindyhopchris commented 1 year ago

I've commented on the JSON:API PR to raise this as something that might need addressing.

jelhan commented 1 year ago

I would recommend discussing specific use cases for linkage rather than discussing it in general. Looking at the example given in the initial post, it seems to be a link to a JSON:API document. That one fits well with the intent of links member. I feel in that case the problem is trying to model two different relationships as a single one.

In your example you have two relationships:

  1. questions: to-many
  2. firstQuestion: to-one

The use case could be solved by modelling them as independent relationships each having a related and self links:

"relationships": {
  "questions": {
    "links": {
      "related": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3/questions",
      "self": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3/relationships/questions"
    }
  },
  "firstQuestion": {
    "links": {
      "related": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3/firstQuestion",
      "self": "http://localhost/api/v1/surveys/4b732db9-48da-43c9-bec0-6df2dc7dcbe3/relationships/firstQuestion"
    }
  }
}

This has multiple benefits:

  1. A generic client would be able to handle both relationships. Custom logic to understand the meaning of an implementation-specific member of the links object is not needed.
  2. A client could request inclusion of the related firstQuestion the same as the client could request inclusion of any other relationship.
  3. As far as I know it is already supported both by the JSON:API specification and the Laravel JSON:API implementation of it.