Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Looking at the following code, there is some developer experience improvements that could be done to make this seem less confusing / forcing developers to review examples.
$data = new ResourceObjectData(array_map(function (NodeInterface $node) {
$resource_type = $this->resourceTypeRepository->get($node->getEntityTypeId(), $node->bundle());
return ResourceObject::createFromEntity($resource_type, $node);
}, $nodes));
It's also missing access checks and other goodies available in JSON API's EntityResource.
Comment | File | Size | Author |
---|---|---|---|
#11 | 3088387-11.patch | 43.61 KB | gabesullice |
#11 | interdiff.txt | 2.26 KB | gabesullice |
#10 | 3088387-10.patch | 43.93 KB | gabesullice |
#10 | interdiff.txt | 56.46 KB | gabesullice |
#6 | 3088387-6.patch | 35.96 KB | gabesullice |
Comments
Comment #2
mglamanHere's a patch. The code was reduced to calling one function exposed from the JSON:API EntityResource controller.
Comment #3
mglamanThis was renamed from the parent so that it makes more sense.
loadEntitiesWithAccess actually returns resource objects, not entities.
Comment #4
gabesulliceI think this exposes too much of the implementation underneath. It seems like a poor DX to pass the entity storage system. It's also a bit heavy handed to enforce access checking IMO. I think this could be a flag that simply defaults to TRUE.
I think this was useful in your initial experiments to minimize coupling and complexity, but since this is an experiment for how to provide something that might eventually be in core, I think it's okay to copy a few more of the internals for EntityResource, rather than just rely on them through this shim.
Given that ^
I got rid of the shim and copied a little bit of EntityResource code and directly injected the EntityAccessChecker. I also made the loader method a little nicer DX-wise.
I'm going to keep working on this, I'd like to make the entity query bit simpler too.
Comment #5
mglamanThis assumes the EntityResource will only perform storage for a single entity type.
I guess that kind of maps how dataProviders in Restful work? But it feels weird that the resource is dictated by a static property.
Comment #6
gabesullice#5: agreed, I got rid of that bit.
This adds the ability to add pagination to a custom collection route with minimal effort. It also does a whole bunch of the boilerplate needed to handle cacheability for the
page
parameter.Honestly, I'm not sure I'm happy with what I have so far. I like the simplicity of the API for extensions for
EntityResourceBase
, but I think there's a lot of somewhat magical stuff going on too. Maybe instead of passingOffsetPaginationEntityQueryModifier
it should instead be a route option in routing.yml, like_offset_pagination: true
.Curious to see what you think @mglaman!
Comment #7
mglamanI agree it'd be nice to have pagination just work. My fear is that we may start adding a lot of arbitrary route defaults that need documentation. Especially as I explore adding magicalness to POST/PATCH.
This is why I thought of originally having plugins. Because it makes this a flag method on the plugin.
This is tightly coupled to the entity query. I could see having the pager beneficial for anything implementing a query interface, such as custom Search API queries (I think the Search API query abstraction implements a relatable interface.) This would fix pagination for a custom Solr resource per https://glamanate.com/blog/using-json-api-query-your-search-api-indexes
I love all of these helpers.
And this one!
I'd honestly prefer if I just passed in my own entity query that I crafted ahead of time instead of having to pass in modifiers. And then the pagination is just a boolean setting.
The DX problem we have is definitely ensuring results are executed in a render context.
If we accepted a query interface (not just entity) we can accept any incoming query (db, search api, etc).
It also removes the need for entity query modifiers. Which lowers complexity
Comment #8
mglamanSearch API would need its own helpers, it doesn't share any of the database query interfaces. That dream is dead :P
Comment #9
mglamanAlso, my fear is that we're going to add additional complexity without exposing proper tools to help developers build with JSON:API instead of putting them into a specific working mindset as the current module does. That's where I think we can be a little more "dangerous" here in this contrib and provide more loose helpers and good examples.
Comment #10
gabesulliceI hear you on the necessity of not being too tightly coupled to entity queries. OTOH, I think most custom collections will still be based on entity queries. I think your examples prove that already. Also, all of the existing pagination/sorting/filtering logic in JSON:API is closely coupled to entity queries.
I think it'd be a gigantic lift to decouple (or rewrite them) to be independent to the entity query system. SO... what does this patch do?
It takes out anything entity query specific from
EntityResourceBase
puts it inEntityQueryResourceBase
.I took your suggestion and nixxed the "modifier" idea. Now you can get a paginator and "apply" it to your raw entity query. It can also generate pagination links.
I threaded cacheability through more things. That's probably just a good thing to do in general.
More helpers.
A couple tests roughly asserting that pagination works as expected.
Comment #11
gabesulliceFixes a few nits.
IMHO, this is good enough to be committed. We can keep iterating on it ofc.
Comment #12
mglamanI say we merge this sucker.
Comment #14
gabesullice🎉