My way from REST to GraphQL
You all know about GraphQL, right? It’s the “new” (actually not new, but things that hype recently just feel like that) hotness when it comes to data exchange through APIs on the web.
I’ve got a pretty good understanding of RESTful APIs, and I’m very used to my current backend stack: Python + Django + Django REST Framework. I created some nifty utility classes that allow for saving nested resources in one go (because we all love transaction safety) and retrieving nested resources contextually — “GraphQL Lite”, so to say.
Why I hate-love REST
Basically everything works, if there weren’t the well-known flaws:
People complain that REST moves too much responsibility to the API server, especially deciding on what data to provide. Instead, the client should ask for the data it needs, reducing bandwidth and computing time, and increasing the fun level.
Another complaint is that not everything can be seen as a resource, making it hard to implement certain features or requirements.
But, on the other hand, REST is super simple, because it limits itself to a
handful of possible operations, mainy creating (
GET), updating (
DELETE) → CRUD!
The way you access resources is also the same, all the time: my.api.com/resources for fetching a list, my.api.com/resources/2 for fetching resource #2 etc.
It’s super easy to grasp and use.
Reasons to leave REST
So why do I want to change protocols? My reasons are simple:
- Stop useless round-trips.
- Stop caring about nested resources.
- Stop caring about optimizing response data (mostly size).
- Stop caring about transaction safety.
Most of my reasons are for making things easier, not making them possible, because I can already solve them all with REST. But I have to put a good amount of effort into it.
GraphQL, my savior?
Somewhere, I guess it was on Reddit, I learned about GraphQL, and people all said it’s the savior to web APIs. After some quick research I was psyched: Yes, indeed, the way GraphQL allows to query for data is just amazing. It’s what REST has always been missing!
Finally I can ask the API server to give me the data I want, in just one request. No more useless overhead, no more useless database hits, no more annoying adjustments for making nested resources work and so much more.
Now what? All problems solved? Ha, watch out for the trap! Whenever you think you found the holy grail in software development, a trap is just waiting for you to step on it.
Either not the holy grail — or I’m missing something fundamentally
Querying, like I said, is superb. You make up your schema, add some security to it and done. It’s really that easy and powerful.
After reading 5–10 (i.e. a lot) articles, including documentation, how-tos, tutorials and others, I wondered why 95% of them are only talking about querying. Either they don’t mention modifying data at all, or just at a glance, including stupid examples.
Unfortunately querying is not what this whole story is all about, is it? Clients want to manipulate data as well: Register accounts, write an article, like a post etc.
And here it comes, the trap: GraphQL has a concept called “mutations”. You use a mutation to change data through the API server — like REST’s POST, PUT or PATCH. However unlike the well-defined operations in REST, GraphQL resorts to RPC: Remote procedure calls.
RPC is one of the main reasons that made us all move away from SOAP and XML-RPC to — guess what — REST.
RPC is awful for web APIs, because it completely violates the DRY principle. You end up writing gazillions of functions to do the same thing: Manipulating well-defined resources.
What to do?
I don’t know. I really don’t. GraphQL looked so promising to me, but it seems like that too less work was put into how data can be easily manipulated, just like you can dead easy query for it.
I really wonder why I just can’t send my data in the way the GraphQL schema is defined, like I can query it.
Granted, it’s no issue for small projects, because the repeated functions are manageable. But for projects with huge resources, I can already see me crying while writing 3 times the same or at least similar code, again and again.