Problem/Motivation
JSON:API has a soft dependency on justinrainbow/json-schema; validation is performed automatically if the dependency is enabled via a check in \Drupal\jsonapi\EventSubscriber\ResourceResponseValidator:
use JsonSchema\Validator;
...
elseif (class_exists(Validator::class)) {
$this->validator = new Validator();
}
@larowlan has previously noted that this causes severe performance issues at runtime, and the fix is to uninstall the dependency.
However, Experience Builder uses justinrainbow/json-schema at runtime (although at the time of writing this is not explicitly declared): #3469516: Declare explicit runtime dependency on `justinrainbow/json-schema`
In turn this will cause performance issues on sites that want to use both Experience Builder and JSON:API.
Steps to reproduce
Proposed resolution
Move ResourceResponseValidator behind some kind of feature flag instead of magically enabling it when the dependency is present. This could be a development mode flag similar to the Twig debug mode, or a feature flag module.
It may even be preferable to move this out of core to a contrib module, as this doesn't feel like it is necessarily in the core use case. Tagging for product manager review. see #2. Also I (bbrala) dont think we should remove it right now.
Remaining tasks
- Discuss the best solution
- Implement.
User interface changes
n.a.
Introduced terminology
n.a.
API changes
New feature flag module jsonapi_response_validator.
Data model changes
n.a.
Release notes snippet
JSON:API response validation has been moved to a separate module as it can affect performance. If you are developing against JSON:API and want to ensure that all responses are correctly formed, install the jsonapi_response_validator module. Otherwise, you should leave this module uninstalled.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3472008
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
longwaveActually given that this is purely a developer-facing feature I am not even sure this is a product manager decision, removing the tag again.
Comment #4
wim leersQuoting @larowlan:
— #3469516-4: Declare explicit runtime dependency on `justinrainbow/json-schema`
As a JSON:API maintainer: +1 for this.
Comment #5
bbralaHmm, automatic discovery is kinda unsettling indeed. I agree that needs to go. I wonder if we will make things less stable if we stop validating. Especially in tests thi has merit. Altough, if performance on this is very bad (have not seem any numbers in the parent) we might want to choose and disable in anyways.
I do kinda agree on ussing a flag perhaps as twig, seems reasonable. Wonder though if we need to change ci then also to enable that. Something like
parameters.jsonapi.validate_schemacomes to mind then.In order to be able to move forwards relatively quicky, this could first just be a parameter defaulting to false if not passed. Then we can consider (and perhaps implement) developer mode in a follow up.
In other news; I was also thinking if this would mean problems in #3031367: Generate JSON schema for content entity types but i think that is all fine.
Comment #6
bbralaWondering, would this same issue exist for:
Drupal\Core\Theme\Component\ComponentValidatorThat kinda does the same.
Comment #8
bbralaTest run results. Kinda weary to do a full conclusion since variance is so high.
So question then becomes. Do we really want this, or perhaps only enable this in testing for a specific node?
Comment #9
bbralaThink this should fail since the validation is off by default now. Lets see if that is the case.
Comment #10
bbralaOk it seems we only have unittests for the code. That is fine, i did a booboo on the unit test arguments though, so lets fix that. Validation should be disbled by default now at least.
Comment #11
bbralaThink this is fine, first time doing a pattern like this, so not sure if this is the right way.
Adding the extra contructor argument shoiuld be fine. We could also do this without a default value if preferred, but this way chances of breaking something seem smaller.
Comment #12
smustgrave commentedCode change looks fine but since it's adding a default service probably needs a change record. Maybe release notes? not 100% on the second.
Comment #13
bbralaCR drafted, child issue for #6 created in #3478689: Investigate if ComponentValidator should have soft dependency on justinrainbow/json-schema
Comment #14
bbralaRebased and small tweak to test method order and comment. All ready.
Comment #15
bbralaComment #16
smustgrave commentedThanks!
CR reads well to me, clearly defines the need and code example makes it look clean.
Ran test-only feature
Which shows coverage.
Rest of the code looks good and believe this is good to go.
Comment #17
longwaveAdded a question about the new container parameter.
Comment #18
bbralaFair point. Will do
Comment #19
longwaveI'm also assuming that this can then be overridden still in a services.local.yml, but haven't checked - we should update the change record to tell people how to reenable the feature.
Comment #21
sumit saini commentedAdded changes as per #17. Also, fixed flag name mismatch in files.
For #19, I have tested and confirm that it is possible to override this container parameter in services.local.yml with these changes.
Comment #22
wim leers#3365985: Promote justinrainbow/json-schema from dev-dependency to full dependency is in.
@catch made an interesting remark over at #3365985-22: Promote justinrainbow/json-schema from dev-dependency to full dependency:
IMHO we should instead pivot this issue to generating such a status report warning instead.
Which … coincidentally is also what @larowlan wrote, see my quote from him in #4!
So: being bold and proposing a rescope of this issue 😇 WDYT?
Comment #23
bbralaSounds like a plan to rescope. +1
Comment #25
anybodyWe just ran into a case where it would have been great to have this to disable response validation. I rebased the MR.
The change record looks correct already?
Comment #27
anybodyUgly hotfix attached to entirely disable JSON:API response validation until this is fixed (MR!13739).
I'll now mark that one as draft to delete once we have a working solution here.
Comment #28
catchI just noticed SDC validation in the theme system, which is behind an assert.
However, the JSON:API validation is not behind an assert at all, so I don't see how this can be fixed with a status report check - bumping to critical.
Comment #29
bbralaI'll put this on my list since it got bumped.
Comment #30
bbralaRebased, updated the change record.
I think we should do the implemntation as is. Allow enabling it through the parameter. Confirmed this in slack with Catch.
Tests are now green, think this is all good now :)
Comment #31
bbralaCreated: #3562208: Add check in status report when "assert" is enabled
Comment #32
catchMR looks good to me. Only question is do we need to put this in default.services.yml or whatever the recommended dev services.yml docs are?
Comment #33
bbralaI was looking around and didnt see many examples of this. But it could be added in
developement.services.yml, this could mean it's at least exposed to developers.It also almost feels like we might as well remove it it this state, who is gonna use this really ever if we hide it away. Also right now it is not even used in testing or anything (which will help speed, but might mean we slip though invalid json).
So i guess if we are to keep it, we need be complete about is and document it, and make sure it is enabled in tests.
(hmm, not making this easier, sorry ;p)
Comment #34
catchRe-titling now that #3562208: Add check in status report when "assert" is enabled is open separately.
Comment #35
bbralaSmall addendum;
core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiTopLevelResourceNormalizerTest.php
that test does check schema's, but with code in the test. So schema's are tested.
Comment #36
longwaveRe #33 I am not sure I elaborated on this anywhere other than the IS but this is why I thought perhaps it should become a feature flag module; that way we can easily enable it in tests or if we decide to get rid of it we can move it out to contrib.
Comment #37
bbralaThat could be a way also yeah.
Which would be pretty small it seems, just add the event (and the test i guess) and enable it in jsonapi tests.
Comment #38
bbralaThat would mean BC break probably though right, since we'd move classes around and change the namespace. :(
That would complicate things
Comment #39
bbralaseems we can do this withouth needing BC since its a subscriber.
Comment #40
longwaveI think we could just move ResourceResponseValidator to a submodule? Quoting the BC policy:
We would still likely need to do this in a minor release whatever we do here, and we've missed the window for 11.3.0 now.
Comment #42
bbralaToo bad about the window, but things happen. Made a new MR to move to a submodule and enabled that in the tests.
Comment #43
longwaveThanks, this looks quite neat, didn't realise it would be quite so simple this way.
I think however we need a requirements hook so the module won't install if the validator library isn't available, otherwise it's not doing what it says it will do?
Comment #44
catchIsn't it always available after #3365985: Promote justinrainbow/json-schema from dev-dependency to full dependency? That was why I bumped this issue to critical.
Comment #45
bbralaYeah that is the point indeed as catch mentioned. Also; the module would allow you to set a validator to use to validate a request if you use setValidator.
Comment #46
bbralaComment #47
longwaveIn which case this is always true I guess
although we could simplify in a followup - there are also PHPStan/typehint issues which I'm on the fence about fixing here.
Comment #48
bbralaMight as well start to clean up a bit if we are not constraint by BC.
Comment #49
bbralaSmall fix since docblocks were wrong. Fun.
Comment #50
bbralaFun depreaction notice. We support 5 and 6 in core. So this deprecated call is needed.
Comment #51
nicxvan commentedYou can add it to the globally ignored deprecations .deprecation-ignore.txt
Comment #52
longwaveNot sure we should ignore globally, because other users of the validator probably should be notified of the deprecation? We can use @phpstan-ignore in the place where we do call it though, and add a @todo to fix when we drop v5 support.
Comment #53
bbralaOkiedokie. :)
#3562477: Drop support for justinrainbow/json-schema:^5
Comment #54
longwaveUpdated IS, couple of questions on the MR still but shouldn't stop anyone else reviewing.
Comment #55
catchI think the SDC issue is #3352063: Allow schema references in Single Directory Component prop schemas which is RTBC but not committed yet (I haven't reviewed it yet so don't know how RTBC).
Comment #56
bbralaComment #57
bbralaMoved some code around to clean up, and I'm questioning the critical prio, still. Good cleanup with more explicit sideeffects.
Comment #58
longwaveNot sure the event subscriber actually works at present - we unit test it but do we need an integration test?
Comment #59
longwaveAlso do we want to remove the assert() here? The module does nothing if assertions are disabled, but it doesn't tell you that.
Comment #60
longwaveIf it turns out that an integration test is hard-to-impossible to write, I question the value of this module at all - is the JSON:API code robust enough that we can trust that it won't fail now? Perhaps this module should just become test-only?
Comment #61
bbralaThinking on this, the code was really for testing only since it is wrapped in assert to actually check. So i think you're right and it is testing only.
I've also manually checked if it runs on tests with:
and have confirmed it works. Did change the services yml though.
Comment #62
bbralaUnrelated test failure.
Comment #65
longwaveLooks good to me, I can't think of a real world case for this unless you are extending JSON:API in some way, in which case you can still use this module in your tests.
I updated the change record a bit to match the new solution and hid the older MRs.
Comment #66
longwaveAlso downgrading to major since #3365985: Promote justinrainbow/json-schema from dev-dependency to full dependency was reverted in 11.3.x, but we should still land this for 11.4/12.0.
Comment #67
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #68
bbralaDid a quick rebase, there were no conflics so setting back to rtbc.
Comment #73
catchCommitted/pushed to main and 11.x, thanks!