Closed (fixed)
Project:
JSON:API
Version:
8.x-1.x-dev
Component:
Code
Priority:
Major
Category:
Task
Assigned:
Issue tags:
Reporter:
Created:
20 Dec 2017 at 12:25 UTC
Updated:
20 Feb 2018 at 10:49 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
gabesulliceComment #3
wim leersComment #4
gabesulliceThe attached begins an implementation of this.
There is a little wonkiness when dealing with related routes and relationships. How should we handle those?
In the case of
uid, the entity reference can only ever point at one resource type. In that case, should skip serialization of the field entirely, or just always serialize anullvalue.OTOH, a field like
field_referencesmight point to many different resource types (because an entity reference can point to more than one bundle type). In this case, we will need to serialize the field even if there's no data.Right now, this patch does nothing to hide the field if it points to a disabled resource, it just always serializes to null. Which might be fine.
Regardless of what we decide above, I realized that
EntityDataDefinitionhasisInternalandsetInternalas available methods (thanks @tedbow). Perhaps we should just be using that instead of this hook mechanism.Postponed for input from @e0ipso and @Wim Leers.
Comment #5
gabesulliceComment #6
wim leersJSON API Extras must already be dealing with this, because it too allows one to remove entity types. Which strategy does it use? And why? We should document it in
jsonapi.api.php.I'd love to see that explored here indeed, so we can remove several of core's
hook_rest_resource_alter()implementations in favor of that, and then core's metadata will also affect the JSON API module. Which means we won't need duplicate hook implementations, as the current patch necessitates.Good call :)
We should mark this
@internal, because we know it will change in the future, so that entity types' metadata can declare whether they're internal or not. (As you already mentioned at the bottom of #4.)This is just a temporary work-around, mirrored after
hook_rest_resource_alter(), and with the same limitations.I'm surprised we need to modify this — I'd have thought https://www.drupal.org/project/jsonapi_extras already had to handle this? Perhaps it forgot to handle this portion?
Comment #7
gabesulliceInstalled it and verified that it does not handle these cases. I also looked through the tests and found nothing that indicates that it should. I created an issue: #2933354: Disabled resources are still accessible via related routes and includes
Comment #8
wim leers👍
Comment #9
e0ipsoThis is totally a bug in JSON API Extras. Although not very important, it needs to be fixed regardless.
Disabling resources was always intended to be an option only at the terminal leaves of the data model tree. The reason is that JSON API (with good criteria IMO) requires you to have full linkage, so intermediate resource types are necessary to reach the desired resource type in the tree. In addition to that, we want all paths to reach from A to B (A ➔ B, A ➔ C ➔ C ➔ A ➔ D ➔ B, …) because they can yield a different set of results.
The problem is that there is no way to determine if a resource type is terminal from the module's perspective. Hence we're allowing disabling any resource, but that requires the good judgement of the implementor. This is even highlighted in the UI in JSON API Extras.
Comment #10
gabesulliceThat makes sense. I think JSON API Extras can benefit from this once we have this figured out. Interestingly, the work going on in #2920194: Inclusion of nested relationships fails for bundle-specific fields will make it impossible to go from A -> C -> B if C is disabled. That's because it relies on ResourceTypes to traverse the field path (unfortunately, this will be yet another dependency on FieldResolver *sigh*).
Comment #11
e0ipsoI'm more optimistic. The field resolver is at the core of everything. Just like the resource types are. It should become ubiquitous, that means that we no longer have coupling between: API public names, field names, Entity Query columns and field properties. To me, that is great news!
Comment #12
gabesulliceHm, thanks for that, you're right :)
Given that perspective, I wonder if there's a way for us to purify that abstraction, make it more explicit, and thereby simplify the rest of the module. To make it blatantly obvious that the module is built on Resources and Fields (which makes sense that it would be... http://jsonapi.org/format/#document-resource-object-fields).
Comment #13
e0ipsoI'm OK with that. I guess we can explore what that would look like. The challenge is not obvious due to the enormous surface we have (think of all the data model combinations possible we are exposing multiplied by the number of interactions among them we support), so I expect a big amount of special cases.
Comment #14
wim leers#9–#13 all sound great, and very insightful :) I hadn't heard of "full linkage", despite having read the entire spec. Just reading it results in less understanding than implementing the spec of course!
And further simplifying sounds like music to my ears!
Comment #15
wim leers#7 + #9 was fixed by @e0ipso in #2933615: Fix related and relationships endpoints for disabled resources (
jsonapi) + #2933354: Disabled resources are still accessible via related routes and includes (jsonapi_extras) AFAICT :)Comment #16
e0ipsoI'm not sure than purify that abstraction, make it more explicit will result on and thereby simplify the rest of the module. But I'm interested to see what Gabe has in mind once he's acquainted with the module's gotchas.
Yep! It was about time we had tests in JSON API Extras. I had hoped that someone would step in for that, but it's been too long and that wasn't happening.
Comment #17
gabesulliceThe attached patch doesn't work. But it would work if core properly provided typed data definitions for entities.
Comment #18
gabesulliceReroll
Comment #19
e0ipsoI think the comment is outdated.
Comment #20
e0ipsoPlease take a look at JSON API Extras to learn about the intricacies of disabling resources. You'll find that there are cases where you want the resource type to get info from it, even if it's disabled.
Comment #21
gabesulliceThis is blocked by: #2169813: Support deriving fields from entity definitions with multiple bundles (or zero bundles)
Comment #22
e0ipso@gabesullice can you please explain why this is blocked?
Comment #23
gabesullice@e0ipso, I've added a core issue that explains the need here:
#2936714: Entity type definitions cannot be set as 'internal'Edit: new issue is actually #2936725: EntityDataDefinition::create() does not respect derived entity definitions
Comment #24
gabesulliceComment #25
e0ipso@gabesullice I still don't see why we need to be blocked waiting on core (potentially it can take months to solve the simplest of things there).
The title says Provide mechanism to exclude "internal" entities until a more generic option is supported by core but then we are postponing waiting on core to support it. It's weird.
We should have an API to disable a resource (see the pointer on #20) and trigger that based on whatever. For now it can be the same hook core uses currently. Whenever a more appropriate solution is provided, we can come back and iterate the trigger.
Comment #26
gabesulliceHad a conversation with @e0ipso about this.
We agree that this issue is soft-blocked by #2936725: EntityDataDefinition::create() does not respect derived entity definitions
However, there is still a way forward on this issue before something lands in core.
isInternalmethod toResourceTypesResourceTypeRepositorywill still return all typesisInternal() == TRUEComment #27
gabesulliceUpdated the issue summary to better reflect path forward in #26.
Comment #28
wim leers#26 sounds like a good plan! Can I summarize it as:
?
Comment #29
gabesullice#28
Yes! That's a good summary.
Comment #30
wim leersCool :)
So should this issue then not be unpostponed? Or do we want to keep this issue for doing ?
Comment #31
gabesulliceWhew, what a sentence! I think we can leave this "postponed" on #2936725: EntityDataDefinition::create() does not respect derived entity definitions. And make a spin-off issue...
#2937279: [META] Introduce concept of internal resource types
Leaving this issue just for actually using the new method.
Updated the IS accordingly.
Comment #32
wim leers😅
I of course should have said
Comment #33
wim leers#2936725: EntityDataDefinition::create() does not respect derived entity definitions landed!
Comment #34
wim leers#2939704: Add ResourceType::isInternal() landed in JSON API! This is still blocked on:
It looks like the "PP" number was only tracking the core blockers, not the JSON API blockers. Updating to reflect the current state.
Although … I'm not sure that it makes sense to block this on #2936714: Entity type definitions cannot be set as 'internal', since that will at best be available in 8.5, maybe only 8.6, but definitely not 8.4. We don't want to wait for 8.5 to update JSON API to do this. So … we won't be able to rely on
EntityType::isInternal()on 8.4 sites anyway.Can't we let JSON API hardcode the assumptions for Drupal 8.4 sites? There's only one entity type that would be considered "internal":
content_moderation_state. That'd allow us to move forward here without #2936714 landing. Although I guess the point is that we wait for #2936714 to land so that we can already be forward-compatible with 8.5/8.6. That'd be ideal!Comment #35
gabesulliceThis is what I planned to do :)
Comment #36
wim leers👌
Comment #37
wim leers#2936714: Entity type definitions cannot be set as 'internal' landed in core this morning!
I committed #2937961: ResourceType should provide related ResourceTypes yesterday!
Which means this is now unblocked :)
Comment #38
wim leersThere now is a sister issue for this against core's
restmodule: #2941622: Make REST's EntityResource deriver exclude internal entity types and mark ContentModerationState entity type as internal instead of the current hack.Comment #39
e0ipsoShould we worry about using core fixes in +8.5 in the contrib codebase? This will break sites running supported core versions. I'm still not sure how to proceed in these cases (this has come up previously).
Comment #40
gabesullice@e0ipso see #35, the plan for BC <8.5 is to "hardcode" the entity types known to be internal prior to the
isInternaladdition.Something like:
Comment #41
wim leersYep.
Can we get a reroll here that is reviewable?
Comment #42
gabesulliceEdit: ignore because of a typo
Comment #43
gabesulliceTypo fixed.
Comment #44
wim leersThis is the key change: that's now setting the new optional
$internalparameter! It uses the API that #2939704: Add ResourceType::isInternal() added.I'd flip this around, so that we will only need to delete lines in the future, rather than modifying each of them:
… oh wait, we'll be able to remove this protected helper method altogether once JSON API requires 8.5! Never mind me :)
Comment #48
wim leersBut I do think the
@todoshould be moved for clarity.Comment #49
wim leersAlso, the issue title is no longer accurate.
Comment #50
gabesullice#49 +1
Updated the title.
Comment #52
wim leers