Problem/Motivation
JSON:API currently exposes all non-internal entity types as resources. This is consistent with the API-First principle that everything on a site that's available via HTML should also be available via an HTTP API. So, if you enabled foo.module, and that module provides a Foo entity type, which people can view and edit via HTML, then on a site with JSON:API installed, those same people should be able to view and edit Foo entities via JSON:API. Without this, entity types available to the HTML site are not available to the site's API consumers, which is pretty much the definition of the site not being API first.
However, in practice, sites might want to use JSON:API in a non-API-first-way. Such as for progressive decoupling, where only certain site features are enhanced with fancy JS. Such a site is not API-First. It's not providing a complete API for external parties to develop complete applications for. For sites such as these, reducing their API surface to only the entity types needed has several benefits, including a reduced attack surface in the case of a security vulnerability.
Proposed resolution
Allow modules to easily declare the entity types they want to use via HTTP. In #3035979-114: [DISCUSSION] Should a facility be added to JSON:API which limits automatic exposure of all entities, this was proposed as a new api_dependencies key in .info.yml files, along with a hook_api_dependencies() hook for modules that require PHP logic in determining their list.
This would, for example, allow a fancy_comments module that implements a Facebook-like commenting UI to declare in its .info.yml that it depends on the comment entity type being available via HTTP APIs. A site builder could then enable JSON:API and fancy_comments, and have this nice UI without having any other entity type exposed.
To retain compatibility with JSON:API's current API-First approach, we could also add a api_first module that implements hook_api_dependencies() and returns every non-internal entity type. So sites that want to be API-First can enable this module.
Remaining tasks
Decide if we want this. As opposed to say, putting JSON:API Extras into core, which has a UI for customizing what's exposed via JSON:API.
Comments
Comment #2
effulgentsia commentedComment #3
effulgentsia commentedComment #4
gabesulliceThis proposal worries me.
I'm worried that if anyone writes libraries for consumers of a headless Drupal site, then they'll also need to provide a Drupal module alongside it. That means it will be more complicated (and therefore more challenging) and the author of that library will have to learn at least basic Drupal development skills too. That seems like it defeats part of the purpose of using JSON:API, a specification-compliant implementation intended to limit the amount of Drupal-specific knowledge required to use Drupal as a backend.
I really believe that #3040354: Introduce entity type annotation key for indicating that an entity type is *safe* for HTTP API usage is the way we should address the concerns raised by this issue. Or, at least, that we should do that first, then evaluate if we still are concerned and re-evaluate if we still feel something like this is necessary.
Comment #5
wim leers@gabesullice in #3040025-8: [meta] Decide on and implement additional security hardenings for JSON:API and other HTTP APIs:
Comment #6
wim leersThis is the concern I share. It could be a way that some decoupled implementations choose to manage the API surface, but we can't make it the norm. And if we can't make it the norm, is this worth the quite significant amount of infrastructure that needs to be created to ensure it is usable and debuggable despite the complexity?
Comment #7
gabesulliceIn #3040025-8: [meta] Decide on and implement additional security hardenings for JSON:API and other HTTP APIs I proposed we close this issue because of the concerns I expressed (copied to #5 above). @Wim Leers agreed with me about my concerns and added concerns about additional complexity. Given that:
I think we should give this 2 weeks from today for @xjm or @effulgentsia (or others) to weigh in otherwise. At the end of that time we can act accordingly.
Comment #8
wim leers@gabesullice in #7:
Tomorrow it'll have been 10 weeks. I think it's time to close this.