flugg / laravel-responder

A Laravel Fractal package for building API responses, giving you the power of Fractal with Laravel's elegancy.
MIT License
865 stars 86 forks source link

GraphQL-style filtering #105

Open flugg opened 6 years ago

flugg commented 6 years ago

By using the only method, the package allows for filtering fields:

return responder()->success(Product::all())->only('id', 'name')->respond();

This works similar to http://graphql.org/ - however, once you start filtering relationships things are looking slightly different. For instance, to filter a product with related shipments, we currently need to use the resource keys of each resource to map their filtered fields, like this:

return responder()->success(Product::all())->with('shipments')->only([
    'products' => ['id', 'name'],
    'shipments' => ['id']
])->respond();

This is the only place in the package we actually use resource keys except for access in the serializers and while it makes sense that shipments is the resource key of the shipments-relationship, it is not so much obvious that the product is mapped to products and not product.

The above form is how Fractal expects the filtered fields, but I believe we can do better and should allow for a more GraphQL-inspired syntax:

return responder()->success(Product::all())->with('shipments')->only([
    'id',
    'name',
    'shipments' => [
        'id'
    ]
])->respond();

I realise most use cases for filtering fieldsets is dynamically through a query string parameter, and then you wouldn't format it in the response either way. However, this might still be wanted in some use cases and makes it a bit more intuitive. The products resource key is still present in the query string:

GET /products?with=shipments&only[products]=id,name&only[shipments]=id

I'm still exploring ideas on how to make that more intuitive as well.