feat: Link-Template (RFC 9652), link sets (RFC 9264) and api-catalog (RFC 9727) - #8468
Open
Spomky wants to merge 3 commits into
Open
feat: Link-Template (RFC 9652), link sets (RFC 9264) and api-catalog (RFC 9727)#8468Spomky wants to merge 3 commits into
Spomky wants to merge 3 commits into
Conversation
Symfony's HttpHeaderSerializer silently drops every link whose href is a URI template, so web links declared with a template on an operation never reached the client. RFC 9652 gives them a home: the Link-Template header field. AddLinkHeaderProcessor now serializes the templated links of the link provider into a Link-Template header, and only sets each header when its serializer produced something. The serializer delegates to symfony/web-link 8.2 and later, and falls back to a backport of it otherwise, as api-platform supports Symfony 7.4. Closes api-platform#6924
Serializes a list of PSR-13 links to an "application/linkset+json" document, grouped by link context then by relation type. Delegates to symfony/web-link 8.2 and later, and falls back to a backport of it otherwise.
RFC 9727 defines the "api-catalog" well-known URI and link relation, and
mandates the RFC 9264 link set format for the document it returns.
GET /.well-known/api-catalog now returns an "application/linkset+json" document,
carrying the profile of RFC 9727, that anchors on the API entrypoint and
advertises the OpenAPI description ("service-desc"), the human-readable
documentation ("service-doc"), the Hydra documentation ("service-meta") and the
exposed collections ("item"). A HEAD request answers with the "api-catalog" link
relation, as section 2 requires, and the entrypoint advertises the catalog with
the same relation so that clients still find it when the API is mounted under a
route prefix.
On Laravel the route sits outside the API prefix, since RFC 8615 roots
well-known URIs at the host.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Three RFCs, three self-contained commits, so they can be split into separate PRs if preferred.
1.
Link-Templateheader (RFC 9652) — closes #6924Symfony\Component\WebLink\HttpHeaderSerializerskips every link whose href is a URI template:So a templated web link declared on an operation was silently dropped:
AddLinkHeaderProcessornow serializes those into aLink-Templateheader:Link-Template: "/books/{id}/author"; rel="author"; anchor="#{id}"Full RFC 9652 support: templated
anchor,var-base, target attributes as structured fieldparameters, and Display Strings for non-ASCII values (
title=%"Bj%c3%b6rn J%c3%a4rnsida").Each header is now only set when its serializer returns something, so a response whose links are
all templated no longer gets an empty
Linkheader.2. Link set serializer (RFC 9264)
ApiPlatform\State\Util\JsonLinksetSerializerturns a list of PSR-13 links into anapplication/linkset+jsondocument, grouped by link context then by relation type.3.
api-catalogwell-known URI (RFC 9727)RFC 9727 mandates the RFC 9264 link set format for the API catalog document, which makes it the
natural consumer of the serializer above.
{"linkset": [ {"anchor": "https://example.com/.well-known/api-catalog", "item": [{"href": "https://example.com/"}]}, {"anchor": "https://example.com/", "service-desc": [{"href": "https://example.com/docs.jsonopenapi", "type": "application/vnd.openapi+json"}], "service-doc": [{"href": "https://example.com/docs", "type": "text/html"}], "service-meta": [{"href": "https://example.com/docs.jsonld", "type": "application/ld+json"}], "item": [{"href": "https://example.com/books"}, {"href": "https://example.com/reviews"}]} ]}Everything is derived from metadata API Platform already has, so there is nothing to configure.
The route is registered with the entrypoint, so
enable_entrypoint: falsedisables it too.Per section 2, a
HEADrequest answers with theapi-cataloglink relation. Per section 3, theentrypoint advertises the catalog with the same relation, which is what lets clients find it when
the API is mounted under a route prefix and the document is therefore not at the host root. On
Laravel the route is registered outside the API prefix, since RFC 8615 roots well-known URIs at the
host.
Notes
[FrameworkBundle][WebLink] Add RFC 9264 link sets and the RFC 9652 Link-Template header symfony/symfony#65428, and fall back to a backport of that implementation otherwise, since
api-platform supports Symfony 7.4. Every duplicated part is marked with a
TODO: remove once "symfony/web-link" >= 8.2 is required.api-cataloglink relation, whichis an additive change to the
Linkheader.HttpOperation::$linksonly reaches the link providerthrough
HydraLinkProcessor, so web links declared on an operation are ignored when Hydra isdisabled. Left untouched here.