Make easier & document validation of required fields in non-form (programmatic API) contexts

Created on 24 April 2024, 8 months ago

Problem/Motivation

From Auto validate fields on $entity->save(), but allow opt-out Closed: works as designed , liquidcms in comment 17 Auto validate fields on $entity->save(), but allow opt-out Closed: works as designed and seconded by Anybody:

I have a REST API which I just noticed is allowing un-validated data into the database (which sadly, causes the node view to wsod) […] i saw the official doc states to run $entity->validate() and then count errors, i would assume before $entity->save() (assuming no errors). Sadly, I marked one of my fields (through the UI) as required; and then in my API code i set it to NULL. This does not count as an error when i run $entity->validate(); so at a loss as to what is the correct approach (or if there is one) to validate an entity.

Another use case: Creating content on CSV import. We output a CSV of all failed rows. Naturally we want things to be consistent and all validation (including the most basic: required fields) to be treated the same whether in the form or through this import. Kind of shocked and appalled that we don't have a straightforward documented way to do that yet!

Steps to reproduce

  1. Configure your content type to have a required field. It is worth stressing that this setting is in the field settings, not the form display settings, which in my opinion makes it a flat-out bug that field/entity validation does not take required fields into account. Say it has machine name field_required.
  2. Follow the documentation on validating entities , and use the validate() method, something like $content = ['title' => 'test']; $entity = $storage->create($content); $entity->validate()
  3. Note the complete lack of validation errors.

Proposed resolution

  • Provide an easy way to include required fields in the validation. It really should be automatic but maybe we could start with allowing a per-bundle opt-in.
  • Identify and fix and/or document any other edge case validation where the API unexpectedly varies from the form.
  • Document really clearly how to do the validation, including everywhere we talk about programmatically saving entities. (Still a surprise to many that it takes an extra step to get constraints to run: blog post, StackOverflow, issue Auto validate fields on $entity->save(), but allow opt-out Closed: works as designed ).

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Feature request
Status

Active

Version

11.0 🔥

Component
Entity 

Last updated about 16 hours ago

Created by

🇺🇸United States mlncn Minneapolis, MN, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @mlncn
  • 🇺🇸United States mlncn Minneapolis, MN, USA
  • 🇨🇭Switzerland berdir Switzerland

    There is the NotNull constraint, added by \Drupal\Core\TypedData\TypedDataManager::getDefaultConstraints().

    There are a number of tests for this, for example \Drupal\KernelTests\Core\Entity\EntityValidationTest::checkValidation(), or \Drupal\Tests\taxonomy\Kernel\TermValidationTest::testValidation(), or rest/jsonapi tests like \Drupal\Tests\jsonapi\Functional\CommentTest::testPostIndividualDxWithoutCriticalBaseFields.

    Maybe something doesn't work correctly for configurable fields, maybe something isn't set up or overrides this? You will have to investigate if you get the constraint added for your field, if it triggers and what it checks.

Production build 0.71.5 2024