7
votes

I'm using Apollo GraphQL on my server, and I'm trying to design my GraphQL API. One question I'm having is whether I should prefer nested queries over root queries or not.

Let's examine both in this example where the current user, me, has many invitations.

Root queries

me {
    id
    name
}

invitations {
    id
    message
}

The resolver for invitations returns invitations for the current user.

Nested query

me {
    id
    name
    invitations {
        id
        message
    }
}

These should achieve the same result, except invitations being nested in the user object me using the latter approach. My concern is though if this works smoothly with Apollo Client in keeping the cache consistent.

What is the recommended way to design GraphQL queries?

2

2 Answers

5
votes

I'd say it really depends on the case. Personally, I treat nested properties as a context: if the API consumer wants to fetch mine notifications, then it's me { notifications { ... } }, not notifications { ... }. If it makes sense to have a top-level key, for example, there's a concept of global notifications (not user-dependent), then go for it. If every user has own notifications (which I assume is true), then me of type User should have it, as every User does. Such generalization encourages reusable thinking: an admin panel, where user(id: ...) { ... } is being used instead of me { ... }, can use the same UI code for free.

As a rule of thumb, it's better to think about consuming that API, not providing it.

3
votes

One of the GraphQL selling point is to allow client to have very much flexibility to define the shape of the data they want to query in a minimised number of requests. They also encourage developers to "Think in Graphs" when designing the schema.

So, I would go for nested query which looks more like a graph. Furthermore, it is much more flexible. If user want to get their user profile data with their invitations, they can get them in a single request only. If they only want to get the profile data, they just ignore the invitation part in the query and server will not waste any resources to get the invitation data due to the design nature of the GraphQL.