As GraphQL is gaining in popularity, misconceptions about how it works and what it provides are also growing. I demystify a lot of these misconceptions in detail in Production Ready GraphQL, but here’s a little top 3 list of misconceptions I see and hear around GraphQL these days.
REST: Requires documentation, GraphQL: Self-documenting
GraphQL is powered by a type system and this type system includes schema member descriptions. This is absolutely great and allows for API providers to describe their API in terms of fields, types, unions, etc. On top of this type system, many tools like GraphiQL for example make it easy to navigate through a schema and see what possibilities a GraphQL API provides.
If you’ve ever tried integrating with an API that is purely documented in terms of fields and types, you probably already suffered from it and know that it is not enough. It is a common issue I see with many GraphQL APIs. So much attention to building an automated reference, but no examples, no tutorials, no descriptions of common use cases, etc. A list of interface types in our schemas does not help clients very much when when it comes to building great integrations, but it is indeed handy as a reference.
So yes GraphQL helps us build great up to date references but the hard part, making sure our documentation can help humans discover what is possible and how to achieve it does not magically appear. Not a lot of API providers do it well, but it’s possible!
I saw a twitter thread the other day where someone was surprised some of their clients were broken when a field was removed from the schema. Someone in the comments commented:
I thought GraphQL was supposed to be free of versioning?
Believe me, I really wish it was possible for GraphQL APIs to make breaking changes without breaking clients, but that’s kind of a contradiction 🙈. Breaking changes (mostly changing, or removing things) in a schema are still a concern with GraphQL. When people say GraphQL is versionless, they mean that GraphQL often favors a continuous evolution approach. This means opting for backward-compatible, additive changes unless absolutely impossible, and using deprecations when needed to have clients move off certain features and discourage new usage.
But that approach is not unique to GraphQL at all, and in fact was around in the web API world way before GraphQL existed. GraphQL is not inherently versionless, but it has certain features that does make it a good choice for opting for API evolution rather than versioning.
- Fields always select the subset of requirements they’re interested in, and don’t get extra bloat by additive changes. That makes it way easier for providers to see how their APIs are getting used and avoid breaking changes.
- Deprecations are part of the specification, which makes tooling and clients deprecation-aware. This is a big deal when it comes to evolving an API in place.
Can’t tell you how many times I’ve had questions like this one:
How do you filter products by <field> and order them by <field>?
GraphQL is not like OData. The specification has absolutely nothing around preexisting filters, pagers or orderings. That’s all up to the specific servers to implement. Some specifications exist around some of these things, but they are generally up to the API providers.
So unless filtering a product by name is explicitly added to a schema as a use case, there is no magical or generic way for a client to instruct a server to filter products by the field name To me this is mostly a feature. Supporting a generic set of filters on the server side can often be a performance and maintenance nightmare. GraphQL APIs also aim to provide client specific experiences, and letting clients fetch from a very generic API like this could go against this vision. There are use cases where you might want to support slicing and dicing data from a GraphQL API. Nothing stops a schema from exposing these generic filters in the schema, it just doesn’t exist by default.
Have you seen any other misconceptions out there? Feel free to share! 👀