Closed (fixed)
Project:
Drupal core
Version:
8.9.x-dev
Component:
jsonapi.module
Priority:
Major
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
23 Nov 2018 at 14:11 UTC
Updated:
3 Apr 2020 at 22:06 UTC
Jump to comment: Most recent, Most recent file




Comments
Comment #2
wim leersInteresting find! We’ll need an explicit regression test for this one for sure. There is an explicit test class just for testing regressions. Perhaps you’d like to contribute the exact test case that you’ve listed here? If you do, I can guarantee that the fix will land tomorrow :)
Comment #3
dagmarThanks @Wim Leers
Instead of providing a regression test, I'm providing general test coverage for the issue described above. It should expose the bug for the specific case I mentioned.
Comment #5
dagmarAs the test runner indicates. The failing tests are associated to the resources that have a id as drupal_internal__id. The ones that don't use id (like vid, tid, etc) are passing.
Comment #6
wim leersWe need to make this either work (200 response), or we need to explicitly say that we don't support this (400 response with helpful error message).
Per https://www.drupal.org/node/2984247 and https://www.drupal.org/node/3015183, I'm inclined to say we don't support this. The error message would then say: .
@gabesullice, @e0ipso: thoughts?
Comment #7
dagmarI guess building a drupal admin UI is not the only case when you would need to access internal ids. If I'm allowed to add another view of this. I wrote an article few months ago about using jsonapi in tests.
So I have a real use case to be able to access internal ids. I think it would be nice to understand why
drupal_internal__idis is being converted to uuid but not the rest of the cases. Seems a bug to me.Comment #8
gabesulliceI don't think either of those CRs indicate that this shouldn't be supported.
drupal_internal__idis in the JSON:API output. We mappedidtodrupal_internal__id(instead of disabling it) specifically in acknowledgement of the fact that there are tightly-coupled yet valid use cases for using Drupal's ID fields.So, I agree with @dagmar that this is a bug that should be resolved.
Comment #9
wim leersGood points! :)
Let's do this then. This then seems like a major bug to me.
Thank you so much, @dagmar, for providing failing test coverage!
Comment #10
gabesulliceIndeed, @dagmar, having that test coverage already written was sooo nice! I tweaked it a little and put it in a place that was more logical to me.
I've attached two patches, once that I think is the "minimal" thing we can do to make this work.
The other is what I'd prefer, because I think it makes things a little bit simpler overall by moving some special cases into a helper method.
Comment #13
gabesulliceThe failures before are caused by bad expectations that weren't updated in #3010432: Filtering by referenced entity requires ".uuid" to be specified in filter path expression. Our test cases were erroneously using
uuidin the filter path and it wasn't causing test failures, meaning what we did in #3010432 let some things slip through, but this new code correctly caught the bad filter paths.Those same failures did not occur on the "minimal" patch, meaning the above bugs were still present. So, I'm dropping the minimal patch in favor of the more comprehensive "preferred" patch.
Comment #14
gabesulliceYes, this is just a reflow. But I've ignored it for too damn long! :P
Comment #15
wim leersThis … is a bit strange. We've now got yet another case of
throw new CacheableBadRequestHttpException(…, 'Invalid nested filtering. The field `%s`, given in the path `%s`, does not exist.', …).Furthermore, this new
isFieldEnabled()helper method seems a bit of a misnomer.I'm hoping you can solve this more elegantly. This method is already very complex, this makes it even more complex (it removes some complexity for sure, but then adds even more IMHO).
I'm very glad to see this disappear. I bit my tongue to not delay the issue that introduced it. But it feels good to see it disappear 👌
Oh, I see! Rather than always disabling the
uuidfield, we first check if its name doesn't happen to beid; if it is, then we don't disable it.Two questions:
A) let's update the comment above it
B) is there a case of this in core?
Comment #16
gabesulliceHmm, what do you think of this? It renames
isFieldEnabledand gets rid of the second exception. It still has the$field_name === 'id' ...ternarys, but I'm okay with thattypeandidare spec defined member names.a) done!
b) No, I thought there was one that came up in tests locally, but I couldn't find one now that I look specifically.
Comment #17
wim leersSo thanks to this new earlier if-test, we know for a fact that
$candidate_definitionswill be non-empty. But we just add anassert()to formally verify that understanding, to catch future surprises early.Looks good!
What do we gain by this inversion?
(All fields are enabled by default, a minority are disabled, so I think what's in HEAD is clearer. Curious about your reasoning.)
Comment #19
gabesullice#17.1 is enabled by #17.2.
There's no way to know if a field actually exists on the resource type without #2 because we only know which fields are mapped and if a field is disabled. But if a field is not mapped and not disabled, then it may or may not exist on the underlying entity type. Now, only fields that exist and are not disabled are "enabled". Hence this comment change:
Comment #20
gabesulliceThis should fix most, but not all of the previous failures. While looking into this, I realized that there's a lot to be desired in this denormalization code. I opened #3017295: Refactor/clean up JsonApiDocumentTopLevelNormalizer::denormalize() and EntityNormalizer::denormalize() for that.
Comment #21
gabesulliceComment #23
wim leers#19: makes sense, thanks!
#20: from 19 to 6 fails, almost there :)
Comment #24
gabesulliceConfig entities--
5 of the 6 failures are caused by config entities for which no properties can be determined without an instance of that config entity in hand and since we don't know about them, they never get put into a field mapping. Now because the above patch changed the "enabled by default" strategy, these config entities started to break because we were asking if unknown fields were enabled or not.
This interdiff now first ensures that we know about the field before we check if it is enabled or not. I reverted the
enabledFieldsproperty back todisabledFields, but I kept the behavior ofisFieldEnabledthat ensures the field also exists. I think that is a more robust/secure behavior.Comment #26
gabesulliceComment #27
wim leersWill this still be true in D9, or will that become required? I think that this at least being considered. Linking to that issue would be good, because that’d allow this to be simplified in the future.
Comment #28
wim leersLet's land this in the next few days.
Comment #29
wim leersAdded an explicit regression test that matches the originally reported issue. That was the most important thing that was missing.
Now the only thing that remains is addressing #27.
Comment #30
wim leersAnd for #27, I think that
config_exportis meant, notconfig_mapping. I searched, and found the relevant issue: #2949021: Deprecate schema fallback in ConfigEntityType::getPropertiesToExport.Comment #31
wim leersComment #34
wim leersFixed the CS violation I introduced in #31. Once it comes back green, IMHO this is committable.
Comment #35
wim leersGreen!
@gabesullice still wrote the majority of this patch; I just reviewed his patches and added an explicit regression test. Committing…
Comment #36
wim leersClarifying issue title, this also matches the original issue report/steps to reproduce and the regression test I added in #29.
Comment #37
wim leersComment #39
wim leersAlso linked this from the change record at https://www.drupal.org/node/3015183.
Comment #41
rpayanmMoving to Drupal core's issue queue.
I'm working on https://www.drupal.org/project/drupal/issues/3122113