DEV Community

loading...

Designing Graphql Schemas: Queries

Brett Jephson
I'm a web developer specialising in frontend technologies. Interested in accessibility, UI and great web experiences. Co-author of The HTML and CSS Workshop, which is published by Packt. he/him
・2 min read

As part of my learning in public drive for the new year, I thought I'd write down some notes as I take in Nik Graf's egghead.io course on Designing GraphQL Schemas.

This will be a series of short posts based on my notes. Starting, in this post, with some good practice for queries and naming fields.

Naming

Managing the fields in a big GraphQL schema comes down to maintaining good naming conventions that make modification and evolution easy.

1. Be specific

Fields should have specific names. For example, if we name a field image and its value is the url of the image of type String:

type Product {
 image: String
}

We might run into problems if we then want to add more fields relating to the image such as a text alternative or description. If we want to change the image field to an Image type with several fields it would cause a breaking change for our clients.

Being specific from the beginning makes the change a lot easier:

type Product {
 imageUrl: String
}

Now we can more easily make the change we want without the risk of angry clients wondering why their api broke:

type Image {
 url: String!
 altText: String
}

type Product {
 imageUrl: String @deprecated( reason: "Use 'image { url }'" )
 image: Image
}

2. Optional Arguments

In a query, optional arguments can cause issues.

For example, you might want to query a page by id or by slug. To do this, we could make both arguments optional:

type Query {
 page(id: ID, slug: String): Page
}

We want to return a page based on either the id or the slug but what happens if we get neither or both? By making these values optional either of these cases is possible.

An alternative is to name multiple queries that take different arguments. Based on our page example:

type Query {
 page(id: ID!): Page
 pageBySlug(slug: String!): Page
}

This prevents those problematic cases and makes it clearer to the client what arguments the query expects.

Discussion (1)

Collapse
willjohnsonio profile image
Will Johnson

These are really good notes! Thanks for sharing