Advice for implementing field whitelists with Symfony/FosRestBundle/JMS Serializer

Viewed 848

I'm currently learning how to implement a relatively simple API using Symfony 3 (with FOSRestBundle) and JMS Serializer. I've been trying recently to implement the ability to specify, as a consuming client, which fields should be returned within a response (both fields within the requested entity and relationships). For example;

  • /posts with no include query string would return all Post entity properties (e.g. title, body, posted_at etc) but no relationships.
  • /posts?fields[]=id&fields[]=title would return only the id and title for posts (but again, no relationships)
  • /posts?include[]=comment would include the above but with the Comment relationship (and all of its properties)
  • /posts?include[]=comment&include[]=comment.author would return as above, but also include the author within each comment

Is this a sane thing to try and implement? I've been doing quite a lot of research on this recently and I can't see I can 1) restrict the retrieval of individual fields and 2) only return related entities if they have been explicitly asked for.

I have had some initial plays with this concept, however even when ensuring that my repository only returns the Post entity (i.e. no comments), JMS Serializer seems to trigger the lazy loading of all related entities and I can't seem to stop this. I have seen a few links such as this example however the fixes don't seem to work (for example in that link, the commented out $object->__load() call is never reached anyway in the original code.

I have implemented a relationship-based example of this using JMSSerializer's Group functionality but it feels weird having to do this, when I would ideally be able to build up a Doctrine Querybuilder instance, dynamically adding andWhere() calls and have the serializer just return that exact data without loading in relationships.

I apologise for rambling with this but I've been stuck with this for some time, and I'd appreciate any input! Thank you.

1 Answers
Related