The GraphQL Sweet Spot
GraphQL is everywhere these days. From Facebook’s original usage of it to some more funky usages like databases, GraphQL is loved by so many developers that we are starting to use it in areas nobody would’ve thought of initially.
Every technology has its use cases for which it is ideal, for which it can work, for which it plain sucks, and everything in between. As developers, we want to pick the right tool for the job, which means understanding our use case and think about what tech might work best for it. This includes the features of the technology itself, but also how familiar we are with it, the community around it, and much more.
I recently spent some time thinking about where GraphQL shines most. We could call it the GraphQL “Sweet Spot”.
Anything close to the middle is where I think GraphQL is a perfect fit. Going towards the exterior of the circle, it’s where I think GraphQL can be used, but maybe it doesn’t benefit from the same advantages. Maybe we can think of it as different “tiers”.
Before we explore these tiers let me make something clearer: even if certain usages of GraphQL are outside the so-called “Sweet Spot”, it doesn’t mean they are completely invalid. It mostly means you might get less of its benefits, or have to invest more tooling to make it more appropriate. It might also mean I’m just behind the times ;).
Tier One
Tier one use cases for GraphQL is using it as an internal API for supporting multiple clients. This is the original Facebook use case and we can expect GraphQL to be optimized for it. So what’s that use case exactly?
We were frustrated with the differences between the data we wanted to use in our apps and the server queries they required. [Source]
Pre-GraphQL, similar concerns were highlighted by Daniel Jacobson. Daniel’s articles are still some of my favorites out there:
REST APIs are excellent at handling requests in a generic way, establishing a set of rules that allow a large number of known and unknown developers to easily consume the services that the API offers.
In this model, everyone knows how to behave and it can be incredibly powerful. The API providers establish a set of rules and the API consumers must adhere to those rules to get what they want from the API. It is perfect, right? In many cases, the answer is obviously yes. But in other cases, as our world scales and the number of ways for people to consume digital content and services continues to expand, this one-size-fits-all model is likely to fall short. [Source]
In both these cases, GraphQL can be seen as a solution to growing pains API providers and clients have when the use cases are powered by a One-Size-Fits-All API and trying to be consumed by a SSKD (Small Set of Known Developers, in Daniel’s words).
GraphQL allows different clients to consume server possibilities in different ways, decoupling the server schema from how clients use it. To me, this is the main reason you would want to look into choosing GraphQL.
This implies you do have pains associated with a One-Size-Fits-All API. You might not. For example, if your API exposes mainly public, unauthenticated, static data, maybe the client flexibility is not worth losing network caching and maybe the overhead of the GraphQL execution engine is not needed.
If we deal with authenticated APIs with volatile data and multiple devices/clients/UIs consume it in different ways, I think GraphQL is a great way to tackle the OSFA problem, at a company scale. Let’s move on to tier two.
Tier Two
Tier two is what a consider very reasonable, and good usages of GraphQL, but maybe not for reasons that are very specific to GraphQL.
The first example is a single frontend client talking GraphQL through an API. Even more popular these days with JAMStack style applications.
With a single client, the concerns of ad-hoc endpoints and managing client-specific server-side resources are not present. These applications love GraphQL for things that are not necessarily unique or inherent to it:
- An amazing ecosystem of tools and libraries.
- A typed schema, and an explicit contract between the API and client.
- Putting more power into the hands of clients.
- A single request to fulfill all clients needs
These are all great things. The reasons why I include this usage context in tier two and not tier one is that because in a single client use case, the overhead of a full GraphQL platform may or may not be needed.
None of the things we listed above need to come from specifically from GraphQL either. A lot of other API styles allow you to use a schema or API description, some of them have great tools, and listening to client use cases should always be on the forefront when designing an API.
With that said, what makes GraphQL still a great choice is that it does bring a lot of these advantages together as a great, ready-to-use package, and all of it is specified. It’s a lot easier to do GraphQL the right way compared to some other API styles that require individual developers to pick the best tools, specifications, and best practices. Having a single client now also doesn’t mean you don’t expect to have the problems associated with supporting multiple internal clients later on, which would make adopting GraphQL a good way of future-proofing (It’s hard to know these things ahead of time though).
Another use case that I consider as tier two is a public GraphQL API. In Daniel Jacobson’s terms again, an API dealing with a LSUD (Large Set of Unknown Developers). On one end, GraphQL seems like the perfect fit for this use case. It makes handling a ton of different client use cases much easier than having to build custom resources or custom RPC calls for all of them. In fact, we can kind of think of it as allowing any client to create their own server-side resources based on a schema. On the other end, GraphQL shines when it defines its possibilities with specific clients in mind. A lot of public APIs have to keep things more generic to allow so many unknown clients to find what they need and to invent things we did not think of in the first place.
As Phil Calcado says beautifully in an article on the BFF Pattern:
To empower third-party developers to build interesting integrations, you need to design an API that makes no assumptions about how the data is going to be used. Source
While that does not make GraphQL a bad choice for a public API by any means, it does mean it forces the server to expose use cases in a more generic way, something that GraphQL APIs usually try to avoid in internal scenarios. With that said, in the end, as I recently tweeted about, it might not even matter if GraphQL is the perfect public API or not if clients enjoy dealing with it and demand it from 3rd party providers.
Tier two is where we see actually the most amount of GraphQL implementations these days. Most likely because the tier one context is a problem that comes much later in the life of a project/company.
Tier Three
Tier three is for interesting use cases but where I find GraphQL provides little to no advantages over other existing options.
One of those is service-to-service communication. As I covered in “Is GraphQL a great choice for east-west service communication?”, service calls often need to be quite optimized for a single use case, and the overhead of a query engine is rarely something that is worth it. When things like gRPC, Twirp, and Thrift exist, it seems to me you would need a very good reason to not use these proven tools and go with GraphQL.
The other one is interacting directly with databases. Developers love the GraphQL query language, but it was never meant to be a generic, powerful query language for databases. It seems it is quite hard to make a case for it, besides the fact it is getting popularity and developers are getting more and more familiar with it.
Again, this doesn’t mean these use cases are completely invalid. Even at tier three we can make an explicit decision of using GraphQL. Good examples of reasons to do so might be for consistency (Using GraphQL already in other areas), internal expertise (The team are experts at GraphQL), or even developer happiness. Things that are harder to measure and will depend a lot on specific scenarios.
Conclusion
So what’s the point of all this? I think the furthest away our problem is from the GraphQL Sweet Spot, the more we need to think about why we want to pick it as our tool of choice. GraphQL, while a really powerful idea, brings some complexity along. Ideally we want that complexity to be a tradeoff we explicitly make because we know GraphQL solves the problem at hand in a great way.
It is amazing though, that because GraphQL brings so many advantages as a single specification, it is an attractive pick to many even though its core properties are sometimes not needed. Something many ecosystems and communities could learn from.
Cheers,
*** originally published on https://productionreadygraphql.com ***