Problem/Motivation
1) In cases where the entity_type is known, it should be passed into Serializer. This will be particularly important if we create an EntityDiff class for PATCH requests.
2) As of drupal-8.0.0-beta6 you still can't do a PATCH or POST using application/json because it will return an
"error": "Entity type parameter must be included in context."
However, using a hal+json and its _links type already works fine to do POST or PATCH.
This patch would allow POST and PATCH using application/json.
Proposed resolution
Add context to the serializer.
Remaining tasks
Needs tests
Needs annotations. See #27
Fix annotations as mentioned by @bertramakers in #13 See instead: #2359245: REST resource plugin annotation class misses some properties
User interface changes
API changes
Original report by @linclark
In cases where the entity_type and bundle are known, they should be passed into Serializer. This will be particularly important if we create an EntityDiff class for PATCH requests.
| Comment | File | Size | Author |
|---|---|---|---|
| #35 | pass_entity_type_into-1964034-35.patch | 2.62 KB | clemens.tolboom |
| #21 | pass_entity_type_and-1964034-21.patch | 2.6 KB | clemens.tolboom |
| #19 | pass_entity_type_and-1964034-19.patch | 2.57 KB | clemens.tolboom |
| #19 | interdiff-1964034-15-19.txt | 935 bytes | clemens.tolboom |
| #15 | pass_entity_type_and-1964034-15.patch | 2.58 KB | clemens.tolboom |
Comments
Comment #1
klausientity_type should not be a problem, we could place serialization context parameters on the resource plugin information.
The subtype is a problem since that information is only present in the data, not in the URL, not in the plugin info, not in some HTTP headers.
Should the deserialization normalizer for entities just perform an entity load if an ID is present? It could get the subtype from the loaded object.
Comment #2
Anonymous (not verified) commentedWould it be possible to pass in subtype information when it is known? For example, if I'm posting a PATCH request to node/1, the system already knows what the bundle is. I'd be fine with not having the bundle on POST or DELETE, but it would be helpful on PATCH.
Comment #3
klausiHere is a patch that demonstrates how the deserialization context could be built. It passes entity_type and resource_id on to the serializer and deserialization chain.
Comment #4
Crell commentedComment #5
Crell commented#3: rest-deserialize-context-1964034-3.patch queued for re-testing.
Comment #7
chx commentedbump.
Comment #8
clemens.tolboomRerolled #3. This needed ->id() and a line removed in core/modules/serialization/src/Normalizer/EntityNormalizer.php which puzzles me.
Let's see what the testbot finds.
Comment #10
clemens.tolboomDrupal\rest\Tests\UpdateTest 59 passes 2 fails
Drupal\rest\Tests\NodeTest 33 passes 1 fails
Comment #11
clemens.tolboomJust use the ->id()
Reverted
Reverted
Comment #13
bertramakers commentedLatest patch fixes the current issue, but seems to break
PATCHrequests (see failing tests).Also the
serialization_contextannotation should be added to theDrupal\rest\Annotation\RestResourceclass so other developers know that it exists, what it does, and how they should use it.Other annotations seem to be missing as well, the class only contains
idandlabelat the moment.Comment #14
clemens.tolboomComment #15
clemens.tolboomAs patch tests fail why not add the request_method back.
Not tested locally due to grogginess
Comment #16
clemens.tolboomComment #17
clemens.tolboom@bertramakers can you please create a new issue regarding the annotations mentioned in #13. It's worth a new one.
Comment #19
clemens.tolboom(sigh) wrong order of setting array (key) value(s)
Comment #20
clemens.tolboom[edit]Irrelevant[/edit]
Comment #21
clemens.tolboomInitialize $context array.
Comment #22
clemens.tolboomCreated issue for #13 #2359245: REST resource plugin annotation class misses some properties
Comment #23
dawehner@clemens.tolboom
I am a bit confused here, the issue title and IS talk about bundles, how they are added here?
Comment #24
clemens.tolboom@dawehner thanks for pointing out my 'blindness'. I did 'just a reroll' :-(
Updated the summary accordingly.
The method \Drupal\rest\Plugin\rest\resource\EntityResource::patch does not use the non-existing EntityDiff either This issue is the only issue mentioning EntityDiff https://www.drupal.org/project/issues/drupal?text=entitydiff&version=8.x
Comment #27
klausiI agree that at least the added serialization_context key should be added to the annotation at Drupal\rest\Annotation\RestResource.
And this needs a phpunit test case which demonstrates that a mocked serializer indeed receives the entity type in the serialization context.
Comment #28
clemens.tolboomThis patch is now also partly implemented in #2291055: REST resources for anonymous users: register
Comment #29
allella commentedThis is comment and a question to hopefully help the next guy who comes along and is testing D8 REST functionality, since the stuff above is pretty technical.
As of drupal-8.0.0-beta6 it seems you can't do a PATCH (or POST according to https://www.drupal.org/node/2098511) using application/json because it will return an
However, using a hal+json and its _links type already works fine to do POST or PATCH.
Is one of the outcomes of this issue, and/or #2291005, that it will soon be possible to do a PATCH or POST with Content-Type: application/json ?
If so, it seems like including
"entity_type": "node"in the application/json
would be necessary, correct?
Comment #30
clemens.tolboom@orangecoat-ciallella you are spot on.
This patch should make Content-Type: application/json work.
Maybe you could update the summary with your text from #29?
Comment #31
allella commentedComment #32
askibinski commentedPatch doesn't apply anymore because EntityDerivative.php doesn't seem to exist anymore. I think it has been renamed to EntityDeriver.php somewhere in the past months. Can't find the related issue though.
Comment #33
clemens.tolboom@anavarre see #2406439: Cleanup EntityDerivative and RouteBuilderInterface
Comment #34
clemens.tolboomRemoved bundle from title and summary
Open issues are
- needs annotation #27
- needs tests #27
Comment #35
clemens.tolboomRerolled.
Comment #36
wwhurley commentedI also needed the $context['entity_type'] to be set. I did that with:
$context['entity_type'] = $definition['entity_type'];
It works, but I'm not entirely sure based on this ticket whether that's the correct way to be doing it or whether it should come from somewhere else.
Comment #37
wim leers#2631774: Impossible to update Comment entity with REST (HTTP PATCH): bundle field not allowed to be updated, but EntityNormalizer::denormalize() requires it also ran into this: for Comment entities, the subtype (bundle, called
comment_typein their case) is not allowed to be modified (by any user, ever). Yet the denormalizer requires it. It therefore required a change in another layer, so the denormalizer gets it (step 1 in the pipeline), but not the entity that ends up being saved — it is stripped by theEntityResource(step 2 in the pipeline).Comment #38
wim leersThis is about Serializer context, so is #2568413: REST views: Pass views style plugin instance to REST Export serializer.
Comment #40
gabesulliceUpdated for 8.2.x and updating issue summary. Without this, it
is impossiblewould most likely require significant effort in the ECK module to POST ECK Entities, while with this applied, it just works.Comment #43
wim leersMy perspective on this has changed since I wrote #37 more than 14 months ago.
We've been able to use the Drupal 8 core REST API just fine all this time, with various entity types. #2737719: EntityResource: Provide comprehensive test coverage: for every entity type, every format, every method and the many follow-ups for it have proven that this is simply not necessary. Therefore, closing this.