OpenAPI: Hide inaccessible links #1518
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR updates OpenAPI to take into account whether JSON:API links are available.
My first take on implementing this was to declare nearly all links as required in the component schemas. Then at runtime remove the links we know can't be returned, which can be determined from the cascading links configuration.
However, because links can be configured per resource type, this requires expansion of the link schema types. For example,
linksInResourceData
becomeslinksInTodoItemData
,linksInPersonData
,linksInTagData
, etc. This introduces many new schemas for questionable gain, as using OpenAPI typically makes users care less about links. But it gets worse. Relationship links can be overruled per relationship within a resource type. This means we need to expand link schema types for them as well. But the relationship links are defined on the relationship left-type, whereas the currently produced schemas for relationships reflect their right-type. For example,todoItems
contains relationshipsowner
andassignee
, both of typepeople
. Let's assume both relationships are required. In that case, a single schematoOnePersonInResponse
is produced for both relationships' right-side types, because they have the same data structure. Now taking expansion for relationship links into account, we'd need to generate separate schemas:ownerToOnePersonInResponse
andassigneeToOnePersonInResponse
. As a result, consumers can't write the following code anymore, because different schemas would be produced:For the reasons mentioned above, I chose not to implement schema expansion at all. The next best thing is to determine which links can be eliminated by taking a union of the configured link types. So if all links are turned off, but
todoItems
turns on the top-levelself
link, then all resource types get only the top-levelself
link. Likewise, if theowner
relationship turns on therelated
relationship-level link, while theassignee
relationship turns on theself
link, then all relationship schemas get both links. If no link overrules are used and links are turned off in options, then no links appear in the component schemas.As a result, all links must be declared as non-required in the component schemas, because now the schemas may contain links that won't actually be returned at runtime (and we haven't eliminated them from the schema).
Closes #1062.
QUALITY CHECKLIST