GraphQL turns 4.
Four years after the release of GraphQL and the supposed death-knell it signaled for RESTful architecture, we can now be a bit more realistic about the current and future state of API development. The numbers don’t lie- GraphQL has seen widespread adoption since its initial release in 2015, surpassing over 2 million weekly downloads on NPM (for reference, React sees about 5 million weekly downloads, while everybody’s favorite Node API web framework, Express, has over 10 million). Make no mistake — GraphQL is showing no signs of slowing down, and it is definitely a worthy addition to the toolkits of front and back-end developers alike.
While GraphQL is undoubtedly a powerful tool, it is important to know exactly when you should implement a single endpoint API. Four years of deployments has taught the community many great lessons about the strengths and weaknesses of a hyper-targeted, just-what-you-asked-for-and-not-a-thing-more, API design.
If you have some experience with building to the GraphQL specification and come from a RESTful background, you will probably agree with the following:
- GraphQL is not a replacement for REST, but rather an alternative.
- Contrary to its name, GraphQL is actually not a query language; it is a specification.
- While there are performance benefits (over REST), they are only apparent in specific situations. It’s still important to pick the right tool for the job.
“GraphQL vs REST: A tale of the tape.”
Let’s face it — REST architecture is prevalent in many company workflows today and will continue to persist for quite some time. Why spend time migrating to a specification optimized for exponentially growing and constantly-evolving resources when all you need to do is offer a small table of data? As it stands in 2019, GraphQL is not a replacement for REST; a similar comparison could be made between choosing a SQL store over a NoSQL database. There are certain applications where it just makes sense to model complex schemas for your API, just as certain cases call for structureless data stores. As an example, GraphQL is great for read-only operations and retrieving data, while REST remains the top choice for inter-application communication. As we see with the numerous and varied offerings of data stores, rather than crowding the space, tailored technologies can have a true, additive value.
“I’ll take one GraphQL please, hold the QL.”
Yes, yes, we know — “But it says QL in the name! What do you mean it’s not a language!?”
Any reasonable person with a knowledge of the expansion of the letters ‘S’, ‘Q’, and ‘L’ probably wouldn’t second a guess at the “QL” in “GraphQL”, yet those same people would probably be surprised to learn that GraphQL is, in fact, not a language at all! True graph languages, such as Cypher (used in conjunction with the Neo4j graph database), share only a titular relationship with GraphQL. GraphQL is simply a syntax (or specification) for designing APIs that is meant to be built around datasets that have many relations (hence the “graph” prefix) and affords the client the ability to query (hence the “query language” suffix) for information in whatever order they please, as long as it falls within the bounds of a schema.
Take this example:
The returned data is massaged into the exact structure of the query that was made, using any server-side language of the developer’s choosing. The client-side requests simply take the form of stringified JSON (which can also be implemented in virtually any programming language) making for an easily digestible, cross-platform, self-documenting, language-agnostic experience. Thankfully for everyone, the most-confusing part of the GraphQL is its name!
GraphQL, a multi-tool for your developer toolbox.
There really isn’t a catch-all solution when it comes to designing APIs so understanding the tradeoffs before making these architectural decisions is instrumental during the application design process.
One of the reasons why GraphQL was developed was to solve the problem of fetching data from multiple networked resources. With REST, many round trips would be required to retrieve the same set of information. This benefit doesn’t come without a tradeoff however, and while it is certainly not an intractable problem, GraphQL is notorious for being difficult to cache. Web caching with REST is a now a nearly decades-old practice (yeah, it’s that old) and is easily configurable while providing immediate performance benefits for frequently retrieved resources.
Similarly, there is a tradeoff when designing a hyper-targeted data-retrieval API for the client using GraphQL. Schemas must be designed to fit certain needs that might have many complicated relations, causing initial back-end logic to become rather convoluted.
Taken together, the significant onus that falls upon the server to do most of the heavy lifting can cause what was previously a straight-forward serving of requests to become a complicated web of interrelations and branching paths. Monitoring the performance of a newly-constructed GraphQL endpoint can add a layer of development to an API that might cause even seasoned developers to balk. Thankfully, As GraphQL increases in popularity, its developer tooling ecosystem responds in kind. Some pretty remarkable engineering can abstract away the development around endpoint monitoring and services like Apollo are becoming the status quo for library implementations of GraphQL endpoints.
While Apollo allows developers to view their endpoint analytics through Apollo Engine, Apollo Engine’s free tier is limited in the amount of qualitative data it provides its users. Other alternatives, such as InQuery (pictured above), are completely free, open-source, and provide extensive information regarding resolver execution speed, frequency, and time. InQuery is a light-weight NPM module that developers can use to decorate their resolvers and start monitoring their endpoint in a few simple steps. Give it a try if you’re interested in monitoring and maintaining the health of your GraphQL endpoint.
There is rarely ever just one solution to a given engineering quandary; REST will continue to remain relevant while GraphQL will continue to climb in popularity. The key is figuring out when each architecture is appropriate. However, given the right application, leveraging the flexibility of GraphQL (accompanied with the correct tools) can prove worthwhile for endeavors toward API optimization.