Open freestyledork opened 1 year ago
I attempted to come up with a temporary solution for not loading sparse fields. Extending the JsonApiResource
and using custom resource classes I can effectively avoid loading unrelated fields. This hasn't been tested in all scenarios. I am not sure if it will work in all combination of available options, but for my initial needs, it's sufficient. Perhaps a head start of some logic needed for v4.
Create a JsonApiResource
class extending the package base class to add a couple helper methods.
/**
* Extract sparse field sets from the provided request.
*
* @param Request $request
*
* @return FieldSets|null
*/
protected function extractSparseFieldSets($request): ?FieldSets
{
if ($request instanceof QueryParameters) {
return $request->sparseFieldSets();
}
if ($request->query->has('fields')) {
return FieldSets::fromArray($request->query('fields') ?: []);
}
return null;
}
protected function getDefaultAttributes($request): array
{
$sparseFields = $this->extractSparseFieldSets($request);
$fields = $sparseFields?->fields()[$this->type] ?? [];
$usingSparseFields = count($fields) > 0;
$schemaAttributes = [];
foreach ($this->schema->attributes() as $attr) {
if ($attr instanceof SerializableAttribute && $attr->isNotHidden($request)) {
$fieldName = $attr->serializedFieldName();
if ( ! $usingSparseFields || in_array($fieldName, $fields, true)) {
$schemaAttributes[$fieldName] = $attr->serialize($this->resource);
}
}
}
return $schemaAttributes;
}
Then from every custom models resource class I just call the $this-getDefaultAttributes($request)
from the attributes function.
@lindyhopchris Do you see any obvious issues with this solution?
Hey! Sorry for not replying to this earlier. I see no problem with that as a temporary solution. I'm planning a permanent solution for the sparse fieldsets as part of all the upgrades I'm working on at the moment.
I know the current version only filters the output for sparse fields. I was wondering if there is an easy fix to avoid loading mutator attributes. I have a few attributes on my models with some complex logic that are getting ran every request when it's not needed resulting in a lot of extra database hits and performance slowdowns. I've tried messing with eager loads, but that gets messy quick. I am open to other solutions, perhaps proxy models? I would prefer keep the calls clean if at all possible.
Any advice is appreciated. Thanks