1

I have a question in regards to designing relationships in REST API's. Imagine I have a relationship like in this diagram

diagram

Now, should I show the relationship in the team endpoint like this?

/v1/teams/:id

{
    id: "66e08a2b-2495-4edc-a528-ef00a3f908f1",
    name: "Sales",
    description: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce tellus odio, dapibus id fermentum quis, suscipit id erat".
    members: [
        {
            id: "a31604c6-2289-4a0b-9127-7219abf4f494",
            name: "John Doe",
            role: "manager"
        },
        {
            id: "fa3c68f4-2008-4bd3-8280-8ae8c4c40a26",
            name: "James Smitt",
            role: "member"
        },
        {
            id: "946d2c3d-415c-4461-850d-892385a65f86",
            firstName: "Jane Doe",
            role: "member"
        }
    ]
}

And an employee endpoint like this:

/v1/employees/:id

{
    id: "a31604c6-2289-4a0b-9127-7219abf4f494",
    name: "John Doe",
    teams: [
        {
            id: "66e08a2b-2495-4edc-a528-ef00a3f908f1",
            name: "Sales",
            role: "manager"
        },
        {
            id: "66e08a2b-2495-4edc-a528-ef00a3f908f1",
            name: "Account management",
            role: "member"
        },

    ]
}

OR should I have a separate endpoint for teammembers?

/v1/teams/:id/members

[
    {
        id: "a31604c6-2289-4a0b-9127-7219abf4f494",
        name: "John Doe",
        role: "manager"
    },
    {
        id: "fa3c68f4-2008-4bd3-8280-8ae8c4c40a26",
        name: "James Smitt",
        role: "member"
    },
    {
        id: "946d2c3d-415c-4461-850d-892385a65f86",
        firstName: "Jane Doe",
        role: "member"
    }
]

And, if I use the separate should I still include the teams and members properties in the employee and team endpoints?

1
  • Graphql was created as a solution to exactly the same problem you are facing. To let the client determine the format in which they, the client, need the data.
    – Andy
    Oct 22, 2020 at 15:21

2 Answers 2

1

should I show the relationship in the team endpoint like this?

There is no particular reason that your resource model should mirror your data model.

The question you are asking is a lot like asking "here is my data model; what should my web site look like?".

One way to look at that is to pay attention to caching, which is an important REST architectural constraint. You can look at the HTTP spec to understand how caching and cache invalidation work.

But the short form - if two pieces of information should be invalidated together, then they should be expressed in the representation of the same resource. If instead they have very different caching characteristics, then you probably want them separated, so that each can have its own caching meta data.

(Think "image in an html page"; its very common for a logo to have very different caching rules compared to the page content, so it makes sense for the logo to be a separate resource. On the other hand, if you have an image that is supposed to be synchronized with the content on the page, then you probably want to embed the image, rather than linking to it.)

But doesn't reducing the number of calls have any kind of benefit? Or does that fall into the category of premature optimization?

No no no -- we're talking about caching, we're already in the world of optimization, so don't fret that.

The question here isn't about benefit, it's about tradeoffs. You do A, therefore you get B, but doing A also inhibits C, so you don't get that. So now you need to start doing the legwork - is the difference between B and not B more favorable than the difference between not C and C? Can you also get D? and so on.

Using a coarse-grained DTO reduces the number of round trips you need to make to fetch the data once, but it also increases the amount of data that you need to move to keep your local copy of the data up to date. At a finer grain, you need more round trips, but those trips are smaller, and you can tune them more precisely (for example, by moving some resources out to a CDN).

Consider, for example: https://softwareengineering.stackexchange.com/

The list of questions updates all the time; the layout (and the java script supporting the layout) changes occasionally; the branding images haven't changed in ages.

Do we really want a single coarse grained policy for all of that? Or are we willing to accept some extra round trips now in exchange for smaller ones later?


The key idea, from my perspective, is this: if we are trying to choose a sensible resource design, then we need to pay a lot more attention to how information changes than we do to how information is stored.

Expressing the same idea another way: none of this matters if your data is static. The interesting choices come from change, and in particular from varying rates of change.

1
  • But doesn't reducing the number of calls have any kind of benefit? Or does that fall into the category of premature optimization? I came to ask myself a question similar to OPs, I have articles of characters in a story which need informations in total of 6 different tables. Wouldn't it make sense to reduce that down from 6 individual calls to a single larger call at one endpoint that collects the entire information for me? Oct 22, 2020 at 6:50
0

Like all things, that is dependent on your requirements. Both options are valid and reasonable on their own. You haven't provided any detail that would suggest one option over the other.

To help with the decision, here are some things to think about:

  • If you are the only consumer of the information, then code to what is most efficient for your needs.
  • If you have external consumers of the information, then code to the interface description.
  • More data takes more time to gather and serialize, sometimes you don't need all of it.
  • Separating data that changes often from data that is mostly static helps when you add caching
  • Each endpoint is more coding and testing required for your application.

There's a lot of reasons why you would want to have the members as part of your JSON object for a team, and a lot of reasons why you might want to separate it out. That said, you could do both--if you had a need to do both.

Bottom line: Decide what your Minimum Viable Product (MVP) is, and evolve from there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.