neomerx / json-api

Framework agnostic JSON API (jsonapi.org) implementation
Apache License 2.0
743 stars 66 forks source link

[Question] How to exclude relationships on collections by default? #241

Closed nanawel closed 5 years ago

nanawel commented 5 years ago

Hi, First of all, thank you very much for your lib. It eases a lot the implementation of a JSON-API compliant server application.

Next, I'd like to know if it's possible (and how) to exclude by default (= when there is no ?include= query parameter) relationships on the items of a collection, when it's the primary data. The reason is quite obvious: retrieveing those data can be very resource-consuming and so the client has to explicitly specified he wants them - and which - when retrieving a collection.

I've thought of extending FieldSetFilter but:

neomerx commented 5 years ago

For example, you may return what you have. If you have full data for a relationship return full data. If you have an only ID (e.g. author_id) then return only the ID and if you have nothing then return just link to the relationship.

In this example it checks actual data in the object and returns either full Author resource or just a link. Also, if you have only ID (e.g. author_id ), you can return only ID with IdentifierInterface like in the example here.

If you want even more advanced things like on-demand deciding if resources should be uploaded from your database it's possible but difficult as you will need to know in your schema what are the filters and include paths in the encoder that calls your schemas. There are some ideas on how to make it easier so let me know if you go this route.

nanawel commented 5 years ago

Hi @neomerx, thanks for your response.

For example, you may return what you have. If you have full data for a relationship return full data. If you have an only ID (e.g. author_id) then return only the ID and if you have nothing then return just link to the relationship.

That's not possible because I virtually have all data when I process the schema. What I don't know is whether I should include them or not.

If you want even more advanced things like on-demand deciding if resources should be uploaded from your database it's possible but difficult as you will need to know in your schema what are the filters and include paths in the encoder that calls your schemas. There are some ideas on how to make it easier so let me know if you go this route.

I think I'll have to investigate this way. I may go with the FieldSetFilter like I said, but I'll need to tune it a little bit. What's problematic anyway is that I might need to create a sub-interface of \Neomerx\JsonApi\Contracts\Encoder\EncoderInterface to add the with* method(s) I need. And with it, a subclass that implements its contract and is able to pass the options to my custom FieldSetFilter.

neomerx commented 5 years ago

@nanawel Would be interesting to see your fork, I might steal some ideas ;)

neomerx commented 5 years ago

@nanawel Also, please have a look at a branch v4-rc. Essentially that's v3 where a Schema has an additional parameter ContextInterface in getRelationships method

    public function getRelationships($resource, ContextInterface $context): iterable
    {
        // ...
    }

Update ContextInterface is a simple getter. You can replace the default implementation with a custom one that optimizes implementation and has extra methods.

nanawel commented 5 years ago

@nanawel Also, please have a look at a branch v4-rc. Essentially that's v3 where a Schema has an additional parameter ContextInterface in getRelationships method

Ooh that's exactly how I was imagining how it could be done. I thougt it was missing a "context" object that could be used by the schema to know what it should return.

As I don't have enough time left on this subject I went with the "return everything even if it's slow" solution, but I should be able to get back on it soon. I'll give your v4 a try!

neomerx commented 5 years ago

@nanawel context added to getAttributes as well. Please update.

neomerx commented 5 years ago

@nanawel Shall I expect any feedback from you on v4?

nanawel commented 5 years ago

@nanawel Shall I expect any feedback from you on v4?

Sorry, not at the moment unfortunately. But I'll give it a shot later. Thanks for your time and your advice anyway. You may close this ticket now.

neomerx commented 5 years ago

Released in v4.