restapi-design

Should I fetch parent resource along with nested resources in one call, fetch them in separate calls, or both (REST API)?


I have an API design question. If I have a resource with nested resources and half the time I need to fetch the parent along with the nested resources from the client, should I use one call to fetch these resources or would it be better (in terms of design) to fetch them in separate calls?

For example, most of the time I need to fetch a Group with its Employees. Would it be better to fetch them in one call or use two different calls (one for Group and another for Employees?

Also, would it be considered a bad practice to conditionally fetch the nested entities from one call with a conditional parameter?

Example: /group?withEmployees=true (fetch group with employees)


Solution

  • I have an API design question. If I have a resource with nested resources and half the time I need to fetch the parent along with the nested resources from the client, should I use one call to fetch these resources or would it be better (in terms of design) to fetch them in separate calls?

    As written, this question doesn't make a lot of sense. That's not your fault: the literature sucks.

    The flaw in your question is this: "resources" are not generalizations of entities in your data model; "resources" are generalizations of web pages.

    Resources are just things that can be identified by a uniform resource identifier. We have primary resources (identified typically by an absolute-URI) and we have secondary resources (some "portion or subset" of a primary resource) identified by referencing a primary resource and additional identifying information in the form of a fragment. Very roughly

    /resources?primary
    /resources?primary#secondary
    

    Therefore, when you ask about /group?withEmployees=true, what you are really asking about here is a new primary resource, which presumably has a different current representation than an existing /group resource.


    most of the time I need to fetch a Group with its Employees. Would it be better to fetch them in one call or use two different calls (one for Group and another for Employees?

    So would it be better to have a single resource with a representation that includes all of the information, or should the information be distributed across two (or more) different resources?

    Answer: Yes, one of these choices is likely to be at least marginally better than the other. But which? is going to be answered by analyzing the trade offs involved, and judging which benefits outweigh which costs.

    For API that are primarily about providing information to the client (in other words, for API that are very much like websites), you're primarily going to be focused on the same sorts of questions that you would ask when designing a website - do we want the same authorization policy on both pieces of information? Do we want the same caching policy on both pieces of information? Do we need to be able to be able to discriminate requests for the information in our tracking / logging? and so on.

    For API where clients are regularly sending information that would change the representations of the API's resources, then you also need to be thinking about the cache-invalidation implications of your designs.


    An example where trade offs matter: in a lot of API, the designers assume that consumers won't ever be pulling data out of cache -- consumers always fetch fresh information from the origin server and act upon that information as soon as it is available.

    And that simplifies things considerably - and works great when it turns out that the assumption is valid.

    Of course, if your API becomes catastrophically successful, your origin servers get pounded, and maybe then you do want to be able to put a general purpose web caching appliance in front of your servers, and the tradeoffs change on you. (And there's nothing wrong with that - needing to update your design decisions because you are trying to carry 100x more traffic than your original targets, and want to continue to grow, is a good problem to have.)