- Again, like I noted in #2829398: Clean up JsonApiResource: the annotation, plugin type, plugin manager, plugin implementations, the dynamic routes generator and the request handler and #2829740: Clean up Drupal\jsonapi\Configuration\Resource(Config|Manager)(Interface) before, it's remarkable how much is tied to entities. I'd again urge you to consider making JSON API support entities only.
Why does this introduce its own interface? Why can't this reuse#2758897 is in, this is no longer an issue.\Drupal\rest\LinkManager\LinkManagerInterface? If the answer isbecause the JSON API module only depends on the Serialization module, not the REST module
, then I'd say: but then let's duplicate REST'sLinkManagerInterfaceuntil it is moved to the Serialization module in #2758897: Move rest module's "link manager" services to serialization module.- I think
\Drupal\jsonapi\LinkManager\LinkManager::getRequestLink()should not be necessary? It should be able to use\Drupal\jsonapi\LinkManager\LinkManager::getEntityLink()? - I think
\Drupal\jsonapi\LinkManager\LinkManager::getEntityLink()should not be necessary; instead the JSON API module should register a new link relation for every entity type. So that you can do$entity->toUrl('jsonapi'). - That leaves just
\Drupal\jsonapi\LinkManager\LinkManager::getPagerLinks(), which AFAICT belongs in aPagerLinkManagerInterface, much like\Drupal\serialization\LinkManager\TypeLinkManagerInterfaceand\Drupal\serialization\LinkManager\ConfigurableLinkManagerInterfacewhich together make up\Drupal\serialization\LinkManager\LinkManagerInterface.
Comments
Comment #2
e0ipsoJSON API only supports entities.
We introduced the plugins in #2781383: [FEATURE] Use plugins for resources because we wanted to keep the door opened to 3rd party modules to configure the resources. This is already in place by allowing resources to be “turned off”.
Comment #3
e0ipsogetEntityLinkit won't work for collections, relationships and related resources.getRequestLink. How would you handle that?Comment #4
wim leersgetCurrentRequestLink().Comment #5
wim leersI see you +1'd #2758897: Move rest module's "link manager" services to serialization module at comment 12.
So, rolled a patch for that: #2758897-13: Move rest module's "link manager" services to serialization module.
Comment #6
e0ipsoComment #7
e0ipsoBlocked by #2758897: Move rest module's "link manager" services to serialization module.
Comment #8
naveenvalechaThis is landed #2758897: Move rest module's "link manager" services to serialization module
It's unblocked now
Comment #9
wim leersIndeed it finally landed :)
IS updated.
We'll still need to figure out how to proceed here.
Comment #10
dawehnerNote: This won't work yet as this requires
\Drupal\Core\Entity\Entityto know that this route needs a UUID.Comment #11
wim leersDamn, we'll need #2353611: Make it possible to link to an entity by UUID for that.
Comment #12
wim leersLooking at this again.
Core's status
So core has this:
interface LinkManagerInterface extends TypeLinkManagerInterface, RelationLinkManagerInterface {}It used to live in the REST module, since #2758897: Move rest module's "link manager" services to serialization module all of that lives in the
serializationmodule.But… all this linkmanager stuff is only ever used by the HAL module's normalizers! And all of it is tied to entity types!!! So it's not at all about generic resources, as one would expect. It all only works for entities. So it's actually
EntityTypeLinkManagerInterfaceandEntityRelationLinkManagerInterface, even if it doesn't want to admit that.So that's two ways in which the link manager is utterly and totally flawed. It'd have been fine if this was the implementation, but the fact that this is an interface means that we're shackled to this API until Drupal 9. We can't even actually sanely expand it with additional kinds of links (because
interface LinkManagerInterface extends TypeLinkManagerInterface, RelationLinkManagerInterface {}).What an utter fail. :(
And then if I go look at where they're used, for example I see this in
\Drupal\hal\Normalizer\ContentEntityNormalizer::normalize():So we get that "type" link from the link manager, but not the "self" link. Sigh. :(
JSON API's status
The JSON API contrib module has this:
It does not extend the existing link manager, because that used to live in REST (which JSON API does not depend on) until just a few weeks ago. However, none of the links in the link manager would actually even be helpful! They all only make sense for the HAL normalization! And even then only for entities!
getEntityLink()clearly fulfills the exact same purpose as this in the HAL module:'href' => $this->getEntityUri($entity),. So we could add agetEntityLink()method to the serialization module's link manager, which could then also be used by HAL's normalizers… but it wouldn't adequately address JSON API's entity link needs, because that$keyparameter there allows also e.g. the "related" link for an entity to be generated.Conclusion
$this->linkManagerappears 0 times incore/modules/serializationand 6 times incore/modules/hal.)Comment #13
wim leersThis resulted in me opening #2854830: Move rest/serialization module's "link manager" services to HAL module.
Comment #14
wim leersSo, based on:
\Drupal\jsonapi\LinkManager\LinkManagercannot possibly build on top of the Serialization module'sLinkManager\Drupal\jsonapi\LinkManager\LinkManageris marked as@internalI'm closing this. The code is good enough for now. There are no abstractions/concepts that this should be building on top of, because they're deeply flawed (as #12 demonstrated). Therefore there is nothing we can do right now, and we do continue to have the ability to make this code better in the future.
Comment #15
e0ipsoThis was a great report Wim. Thanks for uncovering all that. As a matter of fact, the earliest prototypes of JSON API were based on HAL so I did explore re-using the link manager back in the day. I must have come to the same conclusion, but I can remember doing so.
Thanks!