feat(state): cache hydra documentation and entrypoint responses#7929
Open
abderrahimghazali wants to merge 1 commit intoapi-platform:mainfrom
Open
feat(state): cache hydra documentation and entrypoint responses#7929abderrahimghazali wants to merge 1 commit intoapi-platform:mainfrom
abderrahimghazali wants to merge 1 commit intoapi-platform:mainfrom
Conversation
Adds an ETag and revalidating Cache-Control headers to the api_doc and api_entrypoint routes so clients (Admin UI, generated clients, schema parsers) can avoid re-downloading the full documentation when nothing changed. Implemented as a state processor decorating api_platform.state_processor.documentation, mirroring the existing AddLinkHeaderProcessor pattern. The processor computes a strong ETag from the response body and delegates 304 handling to Response::isNotModified(), which respects the client's If-None-Match header. Refs api-platform#4074
24a98c2 to
81420a8
Compare
Author
|
The two CI failures (
For this PR specifically, the 3 files I touched are flagged only for that same Tests for the new processor pass: |
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.
Summary
Adds HTTP caching headers (ETag + revalidation
Cache-Control) to the API documentation (/docs.{_format}) and entrypoint (/{index}.{_format}) routes so clients can skip re-downloading the body when nothing has changed.Fixes #4074.
Why
These two endpoints are hit on every page load by API Platform Admin and any other client that parses the Hydra documentation. The response is often hundreds of KB (one user reports 280 KB / 1.3 s in #4074) and the content rarely changes between requests. Today there is no cache validator at all, so every fetch re-transfers the full payload.
What changes
ApiPlatform\State\Processor\CacheableDocumentationProcessor, a state processor that decoratesapi_platform.state_processor.documentation(the processor used exclusively byEntrypointActionandDocumentationAction).md5of the response body).Cache-Control: public, max-age=0, must-revalidateso clients always revalidate but can serve from local cache while doing so.Response::isNotModified()which short-circuits to a304 Not Modified(with empty body) when the client sends a matchingIf-None-Match.src/Symfony/Bundle/Resources/config/symfony/events.phpas a decorator at priority300(outermost, so it sees the final serializedResponse). The pattern mirrors the existingAddLinkHeaderProcessor.Responsereturns, non-200 responses, or empty bodies — and because it only decorates thedocumentationprocessor, it cannot affect any non-documentation route.This follows the maintainer's suggestion in #4074 ("we must set etags and basic HTTP cache header on these endpoints").
Why a state processor (not a kernel listener)
API Platform 4.x routes documentation through the same state-processor pipeline as resources (
documentation.serializeat 200,documentation.writeat 100). A processor decorator is the idiomatic extension point — it scopes naturally to the two documentation actions (no route-name sniffing onkernel.response), composes with the stopwatch, and matches the precedent set byAddLinkHeaderProcessor.Tests
New
ApiPlatform\State\Tests\Processor\CacheableDocumentationProcessorTestcovers:public,must-revalidate,max-age=0) are set on a 200 response.If-None-Matchmatching the computed ETag yields a304response with an empty body.Response.requestis present in the context.Test plan
./vendor/bin/phpunit --filter CacheableDocumentationProcessorTest(6/6, 18 assertions)src/Statesuite (60/60, 216 assertions)php -lon all changed files