The simplicity with which clients can consume use cases using GraphQL is often balanced by additional complexity on the server. Learn how to manage this complexity and make sure you keep providing a quality GraphQL API as your team or organization scales.
Every language and every GraphQL implementation does things slightly differently. This book is completely language agnostic and instead focuses on concepts and patterns that are achievable no matter how you're building a GraphQL server.
Think of it as a complete journey of what goes into building a GraphQL API, from design, to architectures, to implementation, and even documentation.
Really engaging book about building great GraphQL APIs. Moreover, there's plenty of excellent advice on building APIs and using other API implementations in general which I found really useful and interesting. Highly recommend it to everyone interested in GraphQL and building APIs.
I'm not usually writing reviews anywhere but this book deserves an exception. Anyone involved with a GraphQL implementation, whether to-be or existing, should have a copy of this book.
GraphQL is a paradigm shift when it comes to defining an API and the expected client/server interactions. When facing such a complete overhaul of how to do things, one has to carefully evaluate the nature of the new tradeoffs in order to be successful with their implementation.
Production Ready GraphQL covers each and every aspect of the question: - In depth schema design considerations - Implementing a GraphQL server - Security - Performance and monitoring - Tooling - Workflow (from inception to shipping) - Public vs Internal GraphQL API - GraphQL in a distributed architecture - Versioning - Documentation - Migrating from other API styles
What I liked most is that Marc-Andre Giroux sheds light on both the strengths and weaknesses of the current GraphQL ecosystem, unambiguously. On top of that he manages to do it using a very simple, to the point language that reminds me of "The Pragmatic Programmer" series.
It's an easy read that felt like opening a treasure chest. What could we possibly ask more?
I wish this book was around my company started moving to GraphQL. It would have been the perfect shortcut for the near year of trying to soak up industry best practices in a rapidly developing field. This book will serve as the "GraphQL Bible" for me for years to come.
Self-published, so the page setting is a little strange (I suspect LaTeX) and the text could have used some editing. Switching between first person (we) and second person (you) within the same paragraph forces mental switching on the part of the reader that is not necessary. Giroux should decide if he is with the reader (first person, we) or if he's only talking at them (second person, you), and stick with it. A good editor would have caught this and they would have made the prose tighter. But the author did build GraphQL APIs at Spotify and GitHub, so he knows the material otherwise.
Giroux advocates for building APIs that are as specific as possible, instead of generic ones. Especially when it comes to mutations. The more specific the better.
There is a complex description of cursor-based pagination as opposed to the more common pagination using an offset. The former are more resilient to cases where data gets added or removed in the middle of lists while the end-users are paging through them.
There is an interesting bit about how to deal with errors. The author distinguishes between client errors, essentially protocol errors, and user errors, errors in the business logic. E.g., email already in use, password too weak.
The author acknowledges that GraphQL still needs to grow in a few areas. Companies use it mostly for internal, private APIs. Best practices around error messages and observability (tracing, rate limiting, etc.) are still emerging. When you build a GraphQL client against a published API, you still need to learn the specific ways that API does everything besides queries and mutations.
Giroux provides a code example for schema stitching, which is deprecated, but not for a federated schema, which is an emerging technology. It would have been nice to look at both options side-by-side and show how federation handles some of the limitations of stitching. The Apollo federation equivalent would have been even shorter than the schema stitching code example.
The chapter on documentation is great. The advice is: Don't just provide a dictionary of types and fields. Also provide examples that show how these things can work together to solve problems. Maybe even provide high-level examples that solve business problems using multiple parts of your API.
When the author presents his preferred workflow, it is front-loaded with a lot of analysis. You craft the schema carefully before you implement it, and gather a lot of feedback from beta clients before final publication. This is very much a waterfall process and it does not work well in practice. You need to put things in the hands of users to see how they will use them. There is only so much you can really anticipate, or that the users can tell you ahead of time. We need a technology that can operate in tight feedback cycles and evolve with guidance from real world usage.
At the end of the chapter on versioning, the advice is again big-design-up-front. Giroux is quick to point out the risks of breaking existing clients, but there are also risks to having an API that stagnates and customer features that are not being built in a timely manner. It's a tough act to balance and Giroux's presentation felt one-sided.
GraphQL is a specification for an API query language and a server engine that is capable of executing such queries. It was created and released officially by Facebook in 2015 as a measure to eliminate the differences between the data they wanted to use in their applications and the necessary server queries for them and to provide a more client-focused and experience-driven APIs. Some of the major users of GraphQL are Meta, Github, Twitter, Paypal and other.
Some of the important topics that the book discusses are:
-Designing the GraphQL schema - 4 main points to consider: 1. Use design-first approach to schema development. Discuss design with teammates that know the domain best and ignore implementation details; 2. Design in terms of client use cases. Don’t think in terms of data, types, or fields; 3. Make your schema as expressive as possible. The schema should guide clients towards good usage. Documentation should be the icing on the cake; 4. Avoid the temptation of a very generic and clever schema. Build specific fields and types that clearly answer client use cases.
-Implementing GraphQL servers - these are the ground principles: 1. Prefer code-first frameworks with high extendability; 2. Keep the GraphQL layer as thin as possible and refactor logic to its own domain layer if not already the case; 3. Keep resolvers as simple as possible and don't rely on global mutable state; 4. Modularize when it starts hurting and use your programming language to achieve modularity; 5. Test most of the domain logic at the domain layer; 6. Use visibility filters for small schema variations based on runtime conditions and build different servers at build time when dealing with wildly different schemas;
- Pagination - pagination is almost always essential - most GraphQL APIs today use cursor-based pagination due to Relay's connection pattern which is generally a great choice for accuracy and performance. If page number links are necessary, we should go for offset-based pagination. It is recommended to use the Relay "Connection style" pattern in both cases in order to represent relationships in a better way than simple list types and also to be able to design more complex use cases thanks to the Connection and Edge types.
- Union vs Interface - use interfaces to provide contracts for multiple things that share behaviours but don't overuse them. Use the Union abstract type when a certain field could return different types which don't necessarily share any common behaviours.
- Fine-grained vs Coarse-grained - use coarse-grained Create mutations and fine-grained Update mutations - this is a good approach in most cases. Keep in mind the performance cost of network calls.
-Errors - we divide them into 2 categories - Developer / Client errors (when something went wrong during the query - timeout, wrong ID format, rate limit, etc.) and User errors (when the client did something wrong - email already taken, tries to pay for a checkout twice, etc.). Use the "error" key to handle the Developer / Client errors and define the User errors as part of the schema rather than treating them as exceptions / query level errors. For the second you can use the "Errors as data" approach or the "Union / Result types" approach.
-Rate limiting - there are 2 main approaches: complexity based and time based, which have their pros and cons;
-Authentication - leave authentication concerns out of the GraphQL schema and expect specific session concepts to be present in the GraphQL context when executing a query. Resolvers should not be aware of HTTP headers or tokens. Use standard authentication mechanisms like an authentication middleware.
-Performance monitoring - monitor known queries for their performance and consider passing a client identifier and the client's app version on every call. It is often useful to monitor all the 3 parts of the lifecycles of a GraphQL query (parsing & lexing, validation & static analysis, execution);
Versioning - it's best to keep GraphQL APIs versionless and to go for the Continuous evolution approach;
Some of the most important good practices to consider: - API symmetry (symmetric actions possible given particular entities); - follow the Principle of least astonishment; - be overly specific when it comes to naming schema members; - document GraphQL schema members by using descriptions; - be careful when it comes to setting nullabillity for schema fields; - avoid runtime logic when the schema can enforce it; - use complex object and input types to represent coupling between fields and arguments: avoid "impossible states"; - use default values to indicate default behaviour when using optional inputs and arguments; - fields often should do only one thing (and do it really well) - avoid boolean arguments by splitting the field into to separate ones; - while building your schema, keep in mind that GraphQL's core philosophy is to let the clients consume exactly what they need and go for simple fields that answer specific client's needs (avoid those that are too generic); - the most common problem in GraphQL schemas is the oversharing of types; - resolvers work best as pure functions - they shouldn't depend on the execution order at all; - keep as much business logic out of the GraphQL layer as possible; - keep the context argument as immutable as possible; - don't depend on your fields being called in a certain order, or assume that a certain value in context was filled in by another field; - timeouts are a must in order to avoid long-running queries taking up too much server time - query depth is not so important, complexity and node count are often enough; - persistent queries are a very powerful concept, especially for internal APIs;
Overall, I think the book is greatly written and very informative. I have learned a lot from it and definitely recommend it to everyone who are interested in developing GraphQL APIs.
The book introduces GraphQL and presents its pros and cons and several topics including implementation from the client side, the server side and how to solve different issues and follow good practices.
I started using GraphQL just a month ago and this book gave me a better understanding of the technology and it surely gave me some good ideas to apply in what I'm doing.
If you are starting with GraphQL, it is a good to go.
i really enjoyed this book. my team uses graphql and this book filled in some gaps of knowledge i didn’t know i had. a quick read and a good graphql primer with a surprising amount of depth that i’ll continue to use as reference material going forward
Production Ready GraphQL makes a brief introduction to GraphQL and then covers almost all aspects of it briefly with an emphasis on the Server side of things. Schema Design topic in particular, which is how I know Marc-André from his talks on this topic, is covered very thoroughly as expected. The aim of this book is to give you all the necessary knowledge and suggestions/lessons when building GraphQL Servers.
Marc-André shares very valuable lessons on GraphQL from his years of hands-on experience at Shopify and GitHub, which are the two biggest public GraphQL APIs at the moment. I like the fact that these suggestions are not only hypothetical; but all lessons learned from real life experiences. That can already give you insight about why something is a good, but especially is not a good idea.
Although it has very good information and lessons in it, it gives you the feeling that it is more of a compilation of blog posts than a book. I must say I felt the lack of a structure and a "story"; which made me feel like I was reading Marc-André's blog posts one after another. Individually they are quite good and complete; but together they don't make up a complete book with a structure and story.
This book may not be the starting point for people who are absolutely beginners to GraphQL; but for people who are already building GraphQL APIs for some time and wants to do it right, this book is one of the reference books on server side GraphQL.