Problem/Motivation
As an overall issue based on #2292707: GET on entity/taxonomy_vocabulary/{id} is not working it is weird we cannot POST
/PATCH
/DELETE
for config entities.
This was a key reason for the JS Admin UI initiative being unable to proceed: the config it needed to modify was literally impossible to safely modify through APIs — the validation logic lived only in forms!
- Before #1928868: Typed config incorrectly implements Typed Data interfaces it was impossible for config entities to provide validation on the config level, so it was not possible to guarantee that the given input is valid.
- Before #3324150: Add validation constraints to config_entity.dependencies we had no test coverage to thoroughly test the validatability of config entities.
- Before #3364109: Configuration schema & required values: add test coverage for `nullable: true` validation support we had no mechanism to declare for a config schema type (and every config entity type corresponds 1:1 to a config schema type of
type: config_entity
, for exampleNodeType
→node.type.*
) as "fully validatable".
Proposed resolution
- ✅
Allow config entities to opt into REST support by defining validation constraints for every node in the config schema tree for that config entity type (using the infrastructure that #1928868: Typed config incorrectly implements Typed Data interfaces and #1818574: Support config entities in typed data EntityAdapter added)Done in #3324150: Add validation constraints to config_entity.dependencies + #3364109: Configuration schema & required values: add test coverage for `nullable: true` validation support. - ✅
Leverage config validation to ensure the POSTed/PATCHed entities are validImplemented in this MR 🥳 - ✅
Implement constraints for theThis is obsolete thanks to #2869792: [meta] Add constraints to all config entity types already having marked multiple config entity types as fully validatable 👍config_test
config entity type's entire config schema tree, and implement config validation, to prove that the approach works. - ✅
Open a Plan issue with dozens of child issues to add validation to all other config entity types: #2869792: [meta] Add constraints to all config entity types. - ✅
Expand the test coverage to test schema and constraint validationNOTE: Repeating all the validation test coverage from the
ConfigEntityValidationTestBase
subclasses is pointless. Still, a spot-check makes sense. For that reason,DateFormatTest::testPostValidationErrors()
exists. Compare withDateFormatValidationTest
and the JSON:APINodeTest::testPostNonExistingAuthor()
to verify that this is indeed a consistent DX.NOTE: As soon as this lands, every additional config entity type that is marked fully validatable will have its JSON:API functional tests (guaranteed to exist thanks to
\Drupal\Tests\jsonapi\Kernel\TestCoverageTest
) start failing (guaranteed thanks toResourceTestBase::setUp()
skipping test methods for config entities if and only if the config entity type is NOT fully validatable). That means we will be able to guarantee that everything works consistently 👍 - ✅
→ follow-up: #3423459: [PP-4] JSON:API DELETE support for config entitiestestDeleteIndividual()
akaDELETE
support. Cleaning up deleted dependencies would open up a wormhole for now. - ✅
testRelated()
+testRelationships()
. → Follow-up for "relationships" and "related" created: #3423462: [PP-2] JSON:API relationship/related support for config entities - ✅
Add test coverage to verify that for fully validatable config entity types that 1) use plugins (such asEditor
,FilterFormat
,FieldStorageConfig
, etc.), 2) those plugins have settings, 3) and creating/modifying such a config entity to use a plugin whose settings are NOT fully validatable, should result in either a 422 (like any other validation error), with a message such asThe value at property path foo.plugin_settings.baz cannot be validated. Please contact the developer of the "bar" foo plugin to make this validatable.
#3412361: Mark Editor config schema as fully validatable (Editor
) landed, which made this possible.)
Remaining tasks
- Needs further investigation: #2905594: Missing entity validation constraint: don't allow new entities when there is an existing one with the same ID by @dawehner in #181. This might be a bit of missing test coverage?
User interface changes
None.
API changes
- Addition:
\Drupal\Core\Entity\EntityConstraintViolationList
now accepts not justFieldableEntityInterface
but alsoConfigEntityInterface
- Addition:
\Drupal\Core\Config\TypedConfigManager::getOriginalMappingType()
(although we could do without; it'd just result in duplication of logic) - Change:
ConfigEntityAdapter::validate()
now returns an\Drupal\Core\Entity\EntityConstraintViolationList
instead of a\Symfony\Component\Validator\ConstraintViolationList
, to allow config and content entities to be treated consistently. - Addition: (
@internal
)\Drupal\jsonapi\Entity\EntityValidationTrait::validate()
now also acceptsConfigEntityInterface
and not justFieldableEntityInterface
⚠️ However, any contrib module that:
- provides a config entity type (common)
- subclasses
\Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase
(uncommon) - has made its config entity type fully validatable (rare)
… will start seeing their tests failing due to their test not yet providing a valid POST
or PATCH
document for their config entity (these tests were skipped automatically).
Release notes snippet
JSON:API now supports POST
ing and PATCH
ing config entities that are fully validatable. This enables a whole new world of decoupled Drupal applications.