Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
If you serialize a node and then try to de-serialize it, you get an error.
// Test code.
$options = array(
'type' => 'node',
'content_id' => 1,
);
// Get the serializer service.
$serializer = \Drupal::service('serializer');
$entity = entity_load($options['type'], $options['content_id']);
$json = $serializer->serialize($entity, $format);
$class = \Drupal::entityManager()->getDefinition($options['type'])->getClass();
// Fail!
$new_entity = $serializer->deserialize($json, $class, $format, array('entity_type'=>$options['type']));
Drupal\Core\Entity\EntityStorageException: Missing bundle for entity type node in Drupal\Core\Entity\ContentEntityStorageBase->doCreate() (line 63 of ../core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php).
Comment | File | Size | Author |
---|---|---|---|
#56 | 2451397-56.patch | 17.18 KB | damiankloip |
Comments
Comment #1
Jaesin CreditAttribution: Jaesin commentedGet the bundle by target_id.
Comment #3
Jaesin CreditAttribution: Jaesin commentedBundles are normalized as entity references unless they 'bundle_entity_type' is undefined or "bundle".
Comment #4
Jaesin CreditAttribution: Jaesin commentedComment #6
Jaesin CreditAttribution: Jaesin commentedJust get the bundle by "target_id" if it is set.
Comment #7
alexpottAfter investigating a bit this appears to only be occurring with 'json' serialisation and not 'hal_json'. Patch with a test and a bit more tidy up.
Comment #11
Jaesin CreditAttribution: Jaesin at Chapter Three commentedClean up test and use context over class for denormalization.
Comment #12
Jaesin CreditAttribution: Jaesin at Chapter Three commentedComment #14
Jaesin CreditAttribution: Jaesin at Chapter Three commentedCheck for EntityTypeInterface in \Drupal\serialization\Normalizer\EntityNormalizer::denormalize
Comment #16
Jaesin CreditAttribution: Jaesin at Chapter Three commentedThrow an UnexpectedValueException when a valid entity type is unavailable for denormalization.
Comment #17
Jaesin CreditAttribution: Jaesin at Chapter Three commentedRemove comment and add test only patch.
Comment #19
Jaesin CreditAttribution: Jaesin at Chapter Three commentedMy test changes were stripped, Re-add title assertion.
Comment #21
alexpottThe test looks good and just one more minor nit with the code...
The instanceof check here is superfluous because we've just checked it above.
Comment #22
Jaesin CreditAttribution: Jaesin at Chapter Three commentedIt seems so obvious not that you mention it. ;)
Comment #25
damiankloip CreditAttribution: damiankloip commentedThe only problem now is the _restSubmittedFields property.
Comment #26
Jaesin CreditAttribution: Jaesin at Chapter Three commented@dammiankloip That work is going on over here: #2456257: [PP-1] Normalizers must set $entity->_restSubmittedFields for entity POSTing/PATCHing to work.
Comment #27
alexpottI think this is good to go and we have the followup #2456257: [PP-1] Normalizers must set $entity->_restSubmittedFields for entity POSTing/PATCHing to work to try to remove
_restSubmittedFields
which is not the fault of this patch. I can't rtbc since I contributed to the patch.Comment #28
damiankloip CreditAttribution: damiankloip commentedWe should check the type here too.
This seems like odd behaviour - not a problem with this patch though.
I don't see a need to check the interface here, EntityManager::getDefinition won't return random objects. So this could just check emptiness? However, we currently won't get here anyway as EntityManager::getDefinition() will throw a PluginNotFoundException if the type is not found before here. Unless we add FALSE for the second ($exception_on_invalid) parameter.
This still seems kind of fragile to me, we should be able to have a solution using FieldItemInterface::mainPropertyName()?
If we are keeping this as part of this issue (sigh) then we at least need a @todo linking to the other issue :)
We also need to add to/amend the test coverage in EntityNormalizerTest probably?
Comment #29
damiankloip CreditAttribution: damiankloip commentedJust took a look at the newer approach in #2456257: [PP-1] Normalizers must set $entity->_restSubmittedFields for entity POSTing/PATCHing to work, no more _restSubmittedFields - I love it!
Comment #30
damiankloip CreditAttribution: damiankloip commentedComment #31
Jaesin CreditAttribution: Jaesin at Chapter Three commentedThis approach uses:
Comment #32
Jaesin CreditAttribution: Jaesin at Chapter Three commentedComment #33
alexpottIs this testable?
Patch fixes @todo.
Comment #34
Jaesin CreditAttribution: Jaesin at Chapter Three commentedThis is to allow an entity to be normalized if the bundle it passed like.
Instead of:
Which would otherwise be required and doesn't make much sense considering only one bundle is acceptable.
Comment #35
damiankloip CreditAttribution: damiankloip commentedWe can test that in the unit tests, which need to be amended and extended anyway I think.
Comment #36
damiankloip CreditAttribution: damiankloip commentedThat would throw a notice.
Added checking against available bundles too. That also makes the exception message make a bit more sense.
Comment #38
damiankloip CreditAttribution: damiankloip commentedComment #39
damiankloip CreditAttribution: damiankloip commentedCore is doing that in other places too. Having the bundle entity type defaulting to 'bundle' seems....silly.
Comment #40
damiankloip CreditAttribution: damiankloip commentedComment #41
damiankloip CreditAttribution: damiankloip commentedComment #42
BerdirVery. good thing we have #2346857: Set default property bundle_entity_type in EntityType to NULL :)
Comment #43
damiankloip CreditAttribution: damiankloip commentedYES! That is very good, thanks Berdir!
Comment #44
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedWe can wait on that one now I think and tidy that part I don't like up a bit. Also,not being able to deserialze entities is bigger than 'normal'.
Comment #45
Jaesin CreditAttribution: Jaesin at Chapter Three commentedI was going to let the entity storage handle validating the bundle but this is probably better. ContentEntityStorageBase::doCreate() only checks that a bundle is passed leaving the bundle validation to the field validator.
Comment #46
Jaesin CreditAttribution: Jaesin at Chapter Three commented@damiankloip Thanks for the UnitTestCoverage.
A little more cleanup and additional simpletest coverage and a testonly patch.
Comment #48
Jaesin CreditAttribution: Jaesin at Chapter Three commentedSorry testbot. I forgot a couple of doc blocks.
Comment #49
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedThis line needs a tweak.
Tests*
Otherwise, those changes look ok to me.
Comment #50
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedWe can now simplify this again based on #2346857: Set default property bundle_entity_type in EntityType to NULL
Comment #51
Jaesin CreditAttribution: Jaesin at Chapter Three commentedFixed spelling, simplified the $bundle_entity_type check as per #2346857: Set default property bundle_entity_type in EntityType to NULL and re-wrote the \Drupal\rest\Tests\NodeTest::postNode() docblock description.
Comment #52
dawehnerThat comment is a bit pointless
Nitpick: HTTP instead of http
Let's not introduce a new Safemarkup::format call but use strtr instead
I'm curious whether we should be more explicit, so something like: The specified entity type $entity_type does not exist, but is required for denormalization.
If we want, we could move that to a ternary as well
It is a bit odd to break this ternary into multiple lines
Do you mind splitting up the exception into one which makes it clear that the data does not contain bundle information + one that the specified bundle type does not exist?
Comment #53
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedThanks Daniel, here are some changes based on those comments.
Comment #56
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedComment #59
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedComment #60
dawehnerThank you @Jaesin and @damiankloip
Comment #61
alexpottThe patch has changed a lot since my last involvement. Committed fe81cfa and pushed to 8.0.x. Thanks!
Fixed on commit.
Comment #63
Jaesin CreditAttribution: Jaesin at Chapter Three commentedThe followup to remove the necessity of _restSubmittedFields is over here: #2456257: [PP-1] Normalizers must set $entity->_restSubmittedFields for entity POSTing/PATCHing to work.