GraphQL API Design Best Practices: a summary of “Lessons from 4 years of GraphQL” by Lee Byron
An executive summary of some timeless best practices for designing your GraphQL API’s, excerpted from GraphQL co-founder Lee Byron’s presentation at GraphQL Summit — Lessons from 4 years of GraphQL.
(The full presentation is excellent and available on YouTube here: https://www.youtube.com/watch?v=zVNrqo9XGOs).
In this presentation, Lee outlined some best practices based on 4 years of experience for key questions to leverage when designing your GraphQL interface or API’s.
Even with additional time passing from that presentation, these best practices are still ‘best practices’ imo and valuable insights. Thus I felt it might be helpful to summarize these and make them available in a more compact text format here on Medium, rather than having them available solely embedded within a longer 1 hour plus video presentation.
Thus, some key Best Practices for GraphQL API design, developed by Lee Byron, summarized for your consideration below:
1 — Naming Matters: You can’t expect to go back and refactor once a field name is published, so putting some thought into naming ‘up front’ matters.
A best practice benchmark to guide your naming is this question: “Would a new Engineer understand this?”
You don’t want just ‘good names’, you also want names that are ‘self-documenting’. (Thus no code names or server side tech terms).
Visual tools like GraphiQL are used far more than reading any documentation. Thus, developers are likely to build their queries based solely on field names and hence, the need for clear and self-documenting names.
2 —Think ahead and Design for the future: Naming also matters because GraphQL is designed to be ‘versionless’. In other words, fields may be added over time but ‘breaking changes’ are incredibly rare and avoided at nearly all costs.
Thus you want to think one step ahead with this benchmark question:
Key question: “What would version 2 of the product look like?”
Take the time to think about how your product is likely to evolve and make sure the current API is ready to support that.
3 — Think in Graphs, not Endpoints: You want to think about describing the data you are modeling.
The traditional API approach has been to think about a product experience, and then work backwards to create API endpoints for that product experience.
GraphQL however, exposes all the data from a single endpoint. Thus, you want to focus on describing the semantics of the data you are modeling, and separate out the data from the feature you are building. Effectively, frame the problem as objects in a graph.
Search can be a difficult representation, but Lee presented an idea of providing suggested searches to continue linking objects:
By representing your data as a single, cohesive graph…you create an outcome that allow users to create subsets from your API you might not have imagined. This allows the potential for new product experiences.
4 — Describe the data, not the view: It’s important to model data as objects in the graph. Stay focused on the semantic data and creating a single, cohesive graph. Don’t tie your schema to the demands of the current client.
This ties in with “Think ahead and design for the future” :)
Key question to leverage: “Will this work for future clients”.
Lee presented an example of modeling gift suggestions for an event. On the left is what you might come up with initially from looking at the example view, but on the right is a better model that better models the actual data and not just the view:
5 — GraphQL is a thin interface: You don’t do authentication, etc. in GraphQL. GraphQL sits on top of your existing systems and systems you may build in the future.
Keeping it thin and focused let’s your schema remain robust over time. An illustration from GraphQL.org shows this architecture:
6 — Hide implementation details:
GraphQL interface remains, while the underlying systems and implementations change. If you expose an implementation detail, clients can rely on it. That kind of reliance means as implementations change, it could break clients down the road.
Example: moving from SQL to Mongo, monolith to micro-services, etc.
Thus, hide all implementation details. This lets you prototype fast on the backend, scale, and deploy new services fast while never affecting clients.
Lee noted that while Facebook changed the back-end implementation significantly over four years, the mobile clients (iOS and Android) never had to update their interface schema precisely because their GraphQL schema hides the implementation details.
Key Question: What happens when our implementation changes?
Conclusion: There’s a lot more information in the full presentation, but the key questions Lee presented serve as a great ‘checklist’ to bear in mind as you design your own GraphQL API’s:
1 — Would a new Engineer understand things based on the naming?
2 — What will our next version of the product look like (and will our interface support that vision).
3 — Will this work for future clients?
4 — What happens when our implementation changes?
Lee noted that it’s the above key questions that helped them maintain the same schema over for years while continuing to build and ship new products, features, and deploy new infrastructure.
Hopefully these key questions and the best practices Lee shared above, can help you build and deploy schema’s that can also become timeless schema’s for your GraphQL implementations!
More best practices: The GraphQL site continues with more best practices, including things like pagination and is available here:
GraphQL: A query language for APIs.
The GraphQL specification is intentionally silent on a handful of important issues facing APIs such as dealing with the…
Source / Credits: These best practices are excerpted directly from Lee Byron’s presentation here, and credit to him for an outstanding set of tips and benchmark questions: https://www.youtube.com/watch?v=zVNrqo9XGOs