cloudcreativity/laravel-json-api

How to serve different schema depends on action (read vs. index)?

Closed this issue · 4 comments

I found a solution by myself, but I wonder if is there more generic way?

My solution is to inject IlluminateRoute to my Schema object and then generate response array in getAttributes method depends on getActionMethod or getActionName from route object.

Hi! If you really need to do this, you can use Laravel's request() helper within the schema.

Generally though I wouldn't recommend doing this. Good API design would keep the resource the same regardless which route it is obtained from. If you look at the API docs for any significant API - e.g. Stripe is a good example - the resource JSON is the same whether you receive it from a index, read, create, update etc etc route.

Thank you for your answer. Generally I prefer to use dependency injection instead of Laravel's static helpers, but both method will lead to the same solution.

I understand your point, however it's all about performance and simplicity with lazy loaded relations (my main entity has got ca 9-12 relations on different levels). I load all data once and then I use recurrency to build schema. It gives me very good performance results. I use module param for that to tell api when and which relations should be loaded. However I still need to forbid to load some relations from index and allow them in read. I could use custom controller to filter that param there instead directly on schema or adapter, which probably be better but I need to create custom controller for each resource then.

Yes I prefer dependency injection too. The schemas are created via the service container, so you can type-hint in the contructor if needed.

In the JSON API spec, the eager loading is controlled by the client, not the server. Eager loading is specified in the include query parameter. I.e. a relationship should only be eager loaded if the client has actually asked for it to be included.

If this is a scenario where you only want to allow some include paths on the index route, and not on the read route, then you should look at the Validators class as you can control this via validation.

Validators are indeed the most correct place for that. Thanks for clarification. I'll try to refactor my code to not rely on controller's method directly.