[Question] Eager-loading on specific operations only?
osteel opened this issue · 3 comments
Hi there,
I'm working on a project where users can view their timesheets, which are collections of time entries. They can query them as JSON which is then parsed and displayed in a UI, or they can export the results as a CSV file.
The way I implemented it, the former is done through a regular JSON:API relationship request, e.g.:
[GET] /users/{id}/time-entries
And the latter is done via a custom export
action:
[GET] /users/{id}/time-entries/export
For this I've got a exportTimeEntries
method in the UsersController
controller, and the route is declared like this (shortened for readability):
$api->resource('users')->controller(UsersController::class)->routes(function ($registrar) {
$registrar->field('time-entries')->get('{record}/time-entries/export', 'exportTimeEntries');
});
In exportTimeEntries
, I inject StoreInterface
and FetchRelated
objects so I can basically reuse the same parameters and logic as the regular GET
endpoint to fetch the user's time entries, but instead of returning the collection as is I then export it as a CSV file.
I hope this gives you enough context. Now, the difference between the regular GET
endpoint and the export one, is that for the former the API consumer chooses what resources they want to include with the time entries (such as the related task, so they can display the task name corresponding to the time entry, for instance).
For the export action, however, I know I need these related resources to add the corresponding info to the CSV file, so I want to eager-load them.
Hence my question: is there a way to specify resources to be eager-loaded for a specific action only? Or can I hook into something to add these resource inclusions before the query is executed? I tried to fiddle around the EncodingParameters
objects but got nowhere.
My solution at the moment is to eager-load these resources for all the time entry operations (with $defaultWith
set on the adapter), which is obviously not ideal.
Any ideas?
Cheers,
Yannick
Hmmm... it's been a while, so not sure off the top of my head. Basically what you need to do is manually set the encoding parameters rather than use the ones the client has submitted. I'd need to dig around in the code to find how to do this.
I'm hoping to have some open source time this weekend so will take a look then.
Right, so it looks like I was on the right track with EncodingParameters
?
No worries mate, there's no big rush on this one.
Potentially, but I'm not totally sure until I look at the code. Basically I've spent so much time recently on dev'ing the newly refactored package (laravel-json-api/laravel
) that I can't quite remember all the code in this repo off the top of my head!
Should be able to figure it out once I get a chance to look back over the code in this repo.