- 🇳🇿New Zealand jonathan_hunt
Further to #3100732: Allow specifying metadata on JSON:API objects, there doesn't seem to be a method to inject a
meta
member (https://jsonapi.org/format/#document-meta) at the top level of an API response. Should there be a new issue to address that? My use case is to expose overall content licence and site api version data, independent of the jsonapi version. - 🇬🇧United Kingdom lind101
Not sure if this is the right place for this (please point me in the right direction if there is a more useful place), but just thought I'd drop in a few things that I'm struggling with while developing an API over the last few weeks. These mainly revolving around the extensibility of core JSON:API services due to method access modifiers (predominantly the EntityResource controller class).
What lead me here is I wanted to try and re-use the core code in
EntityResource::getJsonApiParams()
andEntityResource::getCollectionQuery()
in a Custom Resource by calling these methods, but couldn't because they have protected access, I then went down a rabbit hole...For context I'm creating a few Custom endpoints using the JSON:API Resource → module with JSON:API Extras → installed to enable me to easily alias resources and provide defaults, and JSON:API Include → allowing me to provide a cleaner response for the consumer in certain scenarios. Quite the module cocktail!
All of these modules are great and have worked OOB. However a lot of the time they have needed to modify a core JSON:API service, add a "shim" service or create a new service that extend an existing one etc. The main reason for this is to allow them to extend protected methods on the base service. Trying to build on-top of this very tricky when developing a module to extend the core features as you now have to be aware that popular modules (I imagine JSON:API Extras is pretty much a standard) are rolling their own instances of core services so you cannot reliably extend them yourself.
For example jsonapi_defaults part of JSON:API Extras replaces the class used for the
jsonapi.entity_resource
allowing them to add default parameters in the protectedgetJsonApiParams
method. Had thegetJsonApiParams
been public the same could have been achieved with a service decorator, which would then allow other modules to add decorators as well without having to know what other modules are trying to extend these services. As it stands, if I want to extend some functionality to `getJsonApiParams` and retain the functionality provided by jsonapi_defaults, I have to include the jsonapi_defaults module as a dependency and extend that class.As the module ecosystem around JSON:API grows, this is going to a bit of a blocker. Apologies if I don't have the back-story to the method access on these services (I'm sure there is a good reason)!
My two cents (for what it's worth) on things that might help the DX around extending JSON:API:
- Merge functionality offered by JSON:API Extras into core?
- Open up method access on core services. Allowing useful things like:
$params = \Drupal::service(Routes::CONTROLLER_SERVICE_NAME)->getJsonApiParams(Request $request, $resource_type);
$query = \Drupal::service(Routes::CONTROLLER_SERVICE_NAME)->getCollectionQuery($resource_type, $params, $cacheability);
- EntityResource controller is doing too much IMO
- Filter parsing logic could be broken out into a separate public service? This could then be easily extended by decorators.
- Query building logic could be broken out into a separate public service? This could then be easily extended by decorators.
- Response building logic could be broken out into a separate public service? This could then be easily extended by decorators.
- Triggering some events during the execution of all of the above steps might also be an easier way to open it up slightly?
Hopefully that's a useful view of working with the module and it's ecosystem (which is ace btw) and might help a bit with moving it forward. For now I'll build my new features specifically for the application in question as I know what the dependency tree is and can extend the relevant classes.
Cheers! 🤟