GraphQL is the hot new thing right now, bursting into the market as an alternative to REST architecture, solving lots of its problems but also bringing its own. It’s already been adopted by a host of big names, including Facebook, GitHub, PayPal and the New York Times.
At 10Clouds, we decided it’s high time that we tested this new query language, so we set ourselves a simple task: to prepare a proof of concept app aimed at exploring the joys and sorrows of implementing GraphQL API in Django. We wanted to share our findings with you.
This article is for you if:
- You want to find out the basics of GraphQL
- You want to understand its benefits and challenges
- You’re wondering how it compares to REST
- I work as a Python developer at 10Clouds, and am working on Django backends for Web Services, mainly with REST APIs using Django Rest Framework
- We always aim to be at the cutting edge of the latest dev developments and to test them on practical examples
- I take part mostly in startup and new projects, with constantly changing and developing APIs, requiring fast and easy to maintain solutions, like GraphQL
In this post I will shed some light on what exactly GraphQL is, to show how it’s different to REST and present a brief comparison of the two.
GraphQL and REST
GraphQL is a data query language developed by Facebook in 2012 for internal use and open sourced in 2015. It thrives to be the new standard in modern web, focusing on productivity and minimizing data transfer by providing queries where the client decides exactly what he gets.
Using simple yet powerful query language, rather than resting (pun intended) on uncountable endpoints, GraphQL allows focusing on domain and providing data as clear and extensible structure without need to optimize each endpoint separately for specific needs, as it happens to be with REST APIs.
Let’s imagine the classic example of library where we have Books and Authors – each Author has multiple Books and for simplicity each Book belongs to a single Author.
With REST we would probably like to have the following endpoints:
- for list of Authors
- for specific Author
- for a list of Books written by specific Author
- for a list of all Books, maybe filtered by category or language
- for specific Book
Now let’s imagine we have one view that uses only titles of Books from specific author and second that needs their details. Should we always use a list of Books written by specific Author and in the first case just ignore additional data, or should we introduce new endpoint? Or maybe include list of Book titles from an Author in endpoint with his details and leave Book details for others? But what if details about Author are not required either and we just need the titles?
I can keep going with such examples, but I guess the point is clear: with REST API you focus on API structure more than data structure. Each new data structure required needs its own endpoint and each additional endpoint means additional cost and maintenance.
Tackling it with GraphQL
With GraphQL, at least for me, the most important thing is the domain. That can be a big positive but might also bring its own troubles. Our aim should be on representing the domain as clearly as possible, remembering about possible growth in the future. With REST, growth would probably mean refactor, breaking API changes and more and more endpoints. But with GraphQL it should be as easy as adding new fields in existing types allowing for more advanced queries.
Oh yes, queries, as in GraphQL there is only one endpoint where you send an instruction for exactly the data you need. But first, we have to define types as GraphQL is all about types and a clear declaration of things. Because of this, it is not tied to any specific database/storage, all that matters is the data you define (hello there again, domain).
Author will have name, birthday, country and books fields where books is a relation to Book type, probably allowing some filtering. Book on the other hand should have title, page count, language, category and author relation to Author type.
When type definitions and resolvers (other GraphQL thing, it is an instruction on how to get data for a field) are written, we can then start asking questions, or should I say, query them.
Now problems like
Now let’s imagine we have one view that uses only titles of Books from specific author and second that needs their details.
seems trivial, and in fact they are. For the first view it is only a matter of requesting Author by his ID with books field that selects just title field from the Books. Second view would request additional fields on books alongside titles.
These would be sent to the same endpoint, maybe even in one request (as does the query presented above). With REST that would be two separate endpoints, each of them requiring additional work.
Using GraphQL, a developer has to focus on writing type definitions that cover the entire domain, providing some arguments to pass that allow for filtering and selecting specific records based on some criteria. Once this is done, clients can consume this API in any way they need.
Need a new field in the data model? Just add it to a type and define a resolver to it or, the library that your system uses probably already did the latter for you. Now every client can use this new field, and you do not need a new endpoint with it included, as you would with REST.
Oh, and did I mention that you can send multiple queries in one request? So one GraphQL query could ask for all the data, which would otherwise require calling multiple REST endpoints, in a single request to the service, returning everything in one response data object. One request means faster service and less network traffic as only one connection to the backend is required.
Looking at creating your own project in GraphQL? Want to find out more about our work on GraphQL or a range of other platforms? Why not drop us an email on firstname.lastname@example.org or visit our website: www.10clouds.com