fix(jsonapi): allow opt-in client-generated IDs on POST per spec#7930
Open
abderrahimghazali wants to merge 1 commit intoapi-platform:mainfrom
Open
fix(jsonapi): allow opt-in client-generated IDs on POST per spec#7930abderrahimghazali wants to merge 1 commit intoapi-platform:mainfrom
abderrahimghazali wants to merge 1 commit intoapi-platform:mainfrom
Conversation
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.
What's in this PR?
Two related JSON:API issues prevent valid POST requests with client-generated IDs (per JSON:API §7.3):
SchemaFactory) declareddata.idrequiredfor every operation, including the request body of aPOST. The spec saysidMAY be supplied by the client and is otherwise optional on creation.ItemNormalizer) treated any incomingdata.idas a hint to load an existing resource, then either threwUpdate is not allowed for this operationor failed to resolve the IRI when the client passed a fresh UUID.Together they make it impossible to POST
{"data":{"type":"…","id":"<uuid>","attributes":{…}}}even when the application is designed for client-generated identifiers (Doctrine UUID PK, ULID, etc.).Fix
JsonApi\JsonSchema\SchemaFactorySchema::TYPE_INPUTon aPostoperation,data.requiredis now["type"]. Output schemas and non-Postoperations remain["type", "id"](response payloads still always carry anid).buildDefinitionPropertiesSchema()because the relationship loop reassigns\$operation.Before (POST request body):
```json
"required": ["type", "id"]
```
After:
```json
"required": ["type"]
```
JsonApi\Serializer\ItemNormalizerItemNormalizer::ALLOW_CLIENT_GENERATED_ID('allow_client_generated_id').Post, an incomingdata.idno longer triggers an existing-resource lookup.NotNormalizableValueExceptionwith a clear message — no behaviour change for endpoints that don't expect client-generated IDs, and no risk of silently letting a client spoof an ID.OBJECT_TO_POPULATE) is preserved.The flag is off by default to keep the change non-breaking and to avoid an ID-spoofing footgun on public endpoints. Applications opt in per-operation by passing the flag in the denormalization context (or via a state processor / serializer context builder).
Tests
SchemaFactoryTest::testBuildSchemaForPostInputDoesNotRequireId— POST input dropsidfromrequired.SchemaFactoryTest::testBuildSchemaForPostOutputStillRequiresId— POST output still requiresid.ItemNormalizerTest::testDenormalizePostWithIdThrowsWithoutOptIn— POST with client id throws without opt-in.ItemNormalizerTest::testDenormalizePostWithIdSucceedsWithOptIn— POST with client id succeeds with opt-in, IRI converter is not called, id is set on the new entity.Full
src/JsonApi/Testssuite: 57 tests / 145 assertions, all green (the 2 PHPUnit notices are pre-existing).Spec references
Credit to @cay89 for the original analysis in #6738.