Problem/Motivation
#3036593: Add 'drupal_internal__target_id' to JSON:API representation of entity reference fields, because that can't be retrieved from the target resource for target entity types without corresponding resources added a meta.drupal_internal__target_id value on the relationship identifier for entity reference fields; this is super helpful to client-side implementations to filter by Drupal IDs, rather than UUID.
There are some circumstances (user IDs, for instance) where I would like to hide Drupal's internals, entirely. Serial fields in particular can leak information relating to the site's total user count, or the relative age of a user, or whatever, from the ID.
This isn't a huge issue, and enumeration of Drupal users (and other entities) by ID is not considered a security risk per se, but this value's automatic inclusion makes it harder to build a site that is API-forward in using UUIDs everywhere.
Because json:api module exposes a very limited PHP API, this is difficult to adjust in contrib or custom code.
It might be interesting to couple this with an opt-out of all the drupal_internal__* meta members, but this may be too edge a use case to make sense in core. The issue is mostly that this is pretty difficult to opt-out of without hacking core, since there is no real hookpoint to adjust this.
Proposed resolution
Allow the meta member on the resource linkage to omit this Drupalism, by adding a container parameter.
Remaining tasks
Maintainer review... tests maybe?
User interface changes
None.
API changes
New container parameter and change to an internal constructor signature, but this is in the internal API.
Data model changes
None
Release notes snippet
TBD
Issue fork drupal-3257608
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:
- 3257608-allow-opt-out-of
changes, plain diff MR !2032
Comments
Comment #2
bradjones1Comment #3
bradjones1Comment #4
bbralaI understand the desire to remove more drupalisms from the API. Perhaps in the end, giving us a little more control of the meta data could be quite helpfull. Something like what is worked on here #3100732: Allow specifying metadata on JSON:API objects.
Comment #5
bradjones1Yes, that related ticket speaks to part of the equation, though it's mostly about adding meta to resource objects. The drupalisms that I'm referencing here are baked into the json:api normalizers, because they have to be. I don't think adding an event or hook to alter that data is necessary (you can practice dark-arts like extras does, if you really need to override them) but a configuration flag to turn off that behavior might fit into core.
Comment #6
bradjones1AFAICT #3100732: Allow specifying metadata on JSON:API objects would only allow for changing the top-level meta for the resource, but this meta data is included in the resource linkage. So it would need special handling.
Comment #8
bradjones1Comment #9
bradjones1Comment #11
bbralaI was just looking if the referring issue didnt allow this. I mean, if we allow meta to be unset in that even you could remove it there (although that might not be the most performant) since it does allow setting the metadata on the relationships data on a resource. When going through that issue to see if this works i actually found a bug in the MR since it appearantly doesn't handle the /jsonapi/node/article/id/relationships/field_tags kind of endpoint, darnit.
Anyways, i got distracted while reviewing this, it would be nice to be able to remove this from responses and have a clean jsonapi. I have not formed an opinion on the route with a service parameter yet. Sorry, i'll get back to this soon.
Comment #12
ptmkenny commentedI definitely agree with this change. In my case, there are some situations in which I want to hide the ID entirely, and in other cases, I have already exposed, say, the nid to the user, so the meta information is redundant.
What is hopefully an easy question: when using this MR, how do I actually set the container parameter? I tried to search the docs and I found this on creating a custom compiler pass-- is that what I need to do? If you could provide a simple example I would be really grateful.
Comment #13
bradjones1Marking this NW and also this needs extended to hide the same meta information from entity reference items.
Comment #14
bradjones1@ptmkenny you could do so in your site's
default.services.ymlfile or consider using the excellent and very bite-sized https://drupal.org/project/services_env_parameterComment #15
ptmkenny commented@bradjones1 Many thanks!