Let’s go with the Go programming language
What is the Go programming language? Avenga explains use cases of applying it for speedy and efficient software development.
Frederik Berg – Team Lead Engineering Berlin
Pavlo Navalnyi – Front-End Expert
Vladyslav Litovka – DevOps Expert
Andrew Petryk – Java Engineering Manager
René Bannat – Software Developer
Gregory Hasyn – .NET Competency Lead
REST has dominated the landscape of API, but for almost ten years there’s existed a very interesting technology called GraphQL. Some consider it a REST alternative for the future, while some think it is an augmentation for REST only in limited scenarios.
GraphQL is multiple things combined together as a platform: the query language (which the “QL” in its title suggests), client SDKs for multiple languages, server side engine integrating with SQL and NoSQL databases, and the toolset.
So, the topic is big, much bigger than even a series of articles of a similar size, but in this article my goal is to briefly discuss the technology. So we have here more of a what andwhy, and much less of a how.
You can find the tutorial here, if you are interested.
The query language is based on JSON and is standardized. Developers specify what entity they want, designate the filters (criterias), and choose which fields/attributes they want. For example:
{
car(id: "OXY7734773") {
vehicleIdentificationNumber
weight(unit: KG)
}
}
The problem that GraphQL certainly solves is the scenario in which we don’t know what the query is going to be and we want the client to be in control of what data is queried and in which form they want to receive (and modify) it in.
Want a business example?
Let’s imagine an e-commerce application with products that have complex metadate and interface for the user to search for the product using multiple criterias of different data types, some optional, some not, etc. GraphQL is the perfect solution for these types of business cases.
As usual it’s good to recall or summarize the promises of a given technology.
The philosophy of Graph QL is often called a “reverse” to the REST philosophy, in terms of who controls the API – the client or the server.
Imagine you design your application, and design the front end for an API consumer, and you want to fetch some data from the backend API to display it on the screen. You have to find which API calls to make, which data they will return and then aggregate them on the client and display them on the screen.
In other words, in a traditional API design, the API provider (server) decides what data is returned as a response to the call; usually it’s predefined and fixed.
In the case of GraphQL, the client is expected to define what it needs and GraphQL will handle the request and return the data exactly as instructed.
As always, there’s no magic in the tech world. There has to be a GraphQL server on the other side of the call that will translate the GraphQL query to the data stores, then fetch, aggregate and return the results.
This problem is old and so are the solutions.
It used to be one of my favorite questions for interview candidates years ago.
Let’s take an everlasting invoice example. You call the API to get the invoice header data by using one call which returns a NIDs of InvoiceLines (like particular products purchased). Then you have to make N calls for API. If you add the first call, we have to make N+1 calls to the API just to get the entire invoice (single invoice with all invoice lines).
Graph QL enables returning the entire graph of ‘objects’ with one single call and return message. It saves a lot of time wasted otherwise on latency (each call has its cost).
You may disagree with that. You could construct your backend API so it will return the entire graph without even thinking about GraphQL, and you’re right. It’s one of the arguments against GraphQL. Construct good APIs or use a backend for the frontend layer and you can achieve a similar result in a particular case.
But with GraphQL you can solve this problem on the client side.
If we have a strong separation between frontend and backend, or even two different vendors for front-end and backend, GraphQL can ease the conflicts.
GraphQL relies on schema which helps with the data consistency and the early detection of bugs.
REST can benefit from schemas as well, but it’s generally more relaxed in terms of data consistency. Devs often describe REST as “you will find out what your data schema is, once you receive it”.
In GraphQL it’s more structured and up front.
Another advanced feature is the ability to subscribe for data changes and react to those changes using web hooks.
Change Data Capture has been announced by the top tech gurus as an antipattern, and sometimes this approach is one of the very few options available when you cannot touch the back end systems, but want to know if data has changed.
A properly deployed GraphQL engine is able to run queries in parallel to enable faster performance compared to the traditional serialized calls sequence.
This parallelization benefit cannot be taken for granted though and requires the correct configuration.
→ Read how we deliver technology solutions with a clear approach to streamline and accelerate your business.
GraphQL, for me, seems to enforce the view of the system as some kind of bag full of data. API should be the endpoint for business logic, not for data. Not all we do with the system is just to get or write some data. It’s almost like a client-server approach from ancient times, where a client queried a database directly, with tons of client side logic, flow, and business rules. I can imagine the maintenance nightmare.
Front-end developers (especially React devs) seem to like GraphQL a lot for that reason. No more fights with API developers. ‘I’ll just prepare a correct GraphQL query and do what I need to do, so it’s easier and faster’. Yes it is, but just from one side of the spectrum.
How does it hurt us if everyday we have to fetch a little more data than we expect? Like 200 bytes instead of 180 bytes, or even 150 bytes. I don’t think it has any significance in the majority (>90%) of the cases. The N+1 problem is a different story, but it can be solved by providing a proper API for returning the right document structure (object graph). We usually do not require completely different data sets every time and filter/query criteria are often known in advance (IDs, date range, substring).
What cannot be replaced by the simpler REST is (again) the flexibility of executing different queries with future unknown today requirements.
And the wise architect may ask here, “if the requirements change, won’t the API change anyway to reflect that?” But we have to admit there’s tons of flexibility here compared to the traditional ‘server is a master’ approach.
Compared to simple REST/JSON, GraphQL adds complexity on both sides: for the client to prepare the correct query and for the server to run the GraphQL server on top of the data sources. And we all know there’s no free lunch.
Sending different dynamic requests is great for flexibility and the developer’s freedom, but it does not work well with caching.
It’s much easier to do caching with static REST APIs; a higher hit rate and the resulting higher performance.
And this is one of the reasons why the technology is considered to be often overused, or just used without significant benefits, because it’s newer and cooler than this simple, plain, and boring REST.
If the hotness of the technology is the reason for thinking about how to solve complex problems using more advanced solutions (like GraphQL), that’s good, but when the simple trivial problems are looking for complex GraphQL solutions, then it’s the old story of overdesign and overcomplicating things.
The good part of its growing popularity is that the community around it is also growing. So, for both developer-created and natural evolving problems, there are forums with ready to use solutions.
REST depends on HTTP codes to inform the client of the API errors. GraphQL returns HTTP OK (200) and it’s up to the client to figure out the contents of the returned message and determine if there was an error or not.
Some developers prefer this approach, some don’t, because errors are less visible and harder to detect.
For instance, many testing tools or scripts may depend on the http codes to verify test scenarios and in the case of GraphQL, a different approach has to be taken.
It’s not a question of if GraphQL is good or not. It is a very interesting and already mature technology that is supported by major tech players.
The question is, is the added complexity worthwhile in your particular project case. Sometimes the hardest architectural decision is to refrain from using something.
Fortunately it doesn’t have to all be black or white. For instance, you can use GraphQL for complex flexible queries (like in product example) and REST for the more ‘static’ simpler part of your APIs.
We recommend that everyone learn what GraphQL is for, what it is, and to consider its usage in your business applications.
Let’s hear from the voices of our experts and you will see how different teams made different decisions based on their needs and experiences.
What do you like and dislike about it?
Frederik Berg (Team Lead Engineering Berlin):
“I haven’t seen a REST API for years; we usually are talking about and working with RESTful APIs.
If you control both sides, the API provider and the consumer, RESTful allows for tight coupling and very performance optimized routes.
GraphQL allows for loose coupling, which enables you to split very hard responsibilities between the provider and the consumer.
This essentially is a black-box approach; the provider doesn’t know how the frontend works and vice versa.
The provider doesn’t need to know what resources or info the frontend logically needs to achieve a specific goal and therefore can be implemented as an agnostic to these details. This brings freedom and autonomy to a very high degree. But it also means we can not easily tune performance parameters for specific workflows.
The consumer, on the other hand, has freedom and autonomy because it can request whatever it needs, whenever it needs, without creating workload on the provider implementation side. This can lead to faster deployment cycles.
At the same time the frontend does not necessarily have any information on how to optimize requests, which can easily lead to situations where a single request unnecessarily creates queries across multiple db tables.
The consumer team as well, can hardly tune for performance.
You lose the benefits of either if you try to create a RESTful API in a blackbox scenario, or if you try to push for optimizations that need white-box knowledge.”
Pavlo Navalnyi (Front-End Expert):
“From what I’ve seen, it looks much easier to consume, and significantly more flexible and adaptable to different scenarios, such as getting the data from the same source, but in different shapes for different apps (ex. web app and a mobile app).
To me, enabling flexibility seems to be the main point :)”
Vladyslav Litovka (DevOps expert):
“In most cases GraphQL may work, for sure, but from my personal experience that’s not always suitable. Especially when you are building complex business logic behind an API and the Data Model might be changed a bit, however, the public contract can be kept as it is.
But I see no problems if you would need to perform CRUD operations where the good choice is GraphQL .
So, I’m pretty much sure that both approaches would evolve simultaneously.”
Andrew Petryk (Java Tech lead):
“Every time we have tried to implement it, we have fallen back to the default, REST or to gRPC. When the benefits of GraphQL are clear (and Java support is astonishing most of the time), GraphQL is overkill by itself.”
René Bannat (Software Developer):
“I have used GraphQL in a few projects now and I really like how smooth it is to consume on the client side. No more reading a badly written API specification as it comes out of the box via introspection, and with it the schema as a contract between the client and server. I haven’t used GraphQL realtime subscriptions a lot, but I think there are some very interesting use cases for them. I also like the flexibility of how GraphQL can be used. As Fred mentioned, it can hide complexity from the consumer while working as a single endpoint or gateway to an existing RESTful API. Also it can be used for querying data during the build time; e.g., in static site generators like Gatsby.
On the other hand, it always seemed to involve a lot of tooling to set up an API on the server side; simple file uploads can get complicated real quick. There is a huge ecosystem of tools which are still developing and it is hard to choose the right one.
As more and more standards are established in the GraphQL realm I think it will play a major role in the future, whereas RESTful API’s should serve as a fallback to a simpler approach depending on the use case.
As of now, it can’t be seen as a replacement for REST yet, but who knows, if we overcome the challenges of caching and performance, and further work on establishing a new standard, maybe it would make RESTful API’s obsolete one day.”
Gregory Hasyn (.NET competence lead):
“Our team experience is just from the sandbox, and every time we get some hybrid of REST wrapped by GraphQL (sure, it is due to a lack of mind shift to GraphQL).
I know of only two success stories of migration from REST API to GraphQL, the result of which I observe daily, and they are GitHub and PayPal.
If you try to search for another success case, Google returns the result which leads to a page with 404 (describable to some degree;).”
→ Read about a wide range of services Avenga provides to evaluate, benchmark, manage, and increase your business value.
* US and Canada, exceptions apply
Ready to innovate your business?
We are! Let’s kick-off our journey to success!