The Backend topic on Frontend House channel? Yes! Meet the first backend episode on our channel - GraphQL by Przemyslaw. At Frontend House, our experts will deal with complete digital solutions: frontend, backend, design.
Ok, so let's focus on GraphQL. What is it? Can we call him the successor to REST API? Which of these two approaches we should use in our application? Watch the newest episode to learn all the details.
Hello everyone! My name is Przemyslaw Luczak and I’m a Java developer at Frontend House/Liki Mobile Solutions. Today, we will talk about GraphQL, whether it’s a successor to REST API, and which of these two approaches we should use in our application. But first, it’s time for an intro.
In the beginning, let me share the agenda. For starters, I would like to briefly tell you what GraphQL is all about. Then I will tell you what are the elements of GraphQL. We will take a closer look at particular elements such as schema, types, queries, mutations, and resolvers. In the next point, we will look at an example of CRUD implementation, using Java and the Springboot framework. After the practical part, I will present the pros and cons of GraphQL and then compare it with the REST approach. Next, I will try to give you a tip, on when we can use this technology. And finally, I will summarize today’s topic.
What is GraphQL?
Let’s start. What is GraphQL? It was created by Facebook as the answer to the efficiency problem of loading the newsfeed on mobile phones. GraphQL is a query language for APIs and a runtime for fulfilling those queries with your data. A GraphQL-based server, unlike a REST server, offers only one endpoint that expects a wellformed query. It’s the client's decision, what data he wants to receive in the response. It means, that the Client in the request, defines the structure of the response, coming from the server. Thanks to this, communication between the Server and the Client is optimized. As with the REST API architectural pattern, GraphQL is platform and language independent. GraphQL consists of a type system, a query language, execution semantics, static validation, and type introspection. It supports reading, writing, and subscribing to changes. And this is another point of today’s presentation.
Let’s analyze the components of GraphQL which are schema, types, queries, fragments, mutations, and resolvers.
GraphQL requires a fixed schema to describe the server’s API. There is information about queries, types, mutations, resolvers, and the other components of our API. You have to remember, that GraphQL is strongly typed, and requires that type of information, which is part of the schema.
The main components of the GraphQL schema are object types, which represent objects or their properties. The second part of the schema is Root Types which correspond to the download, modification, and observation actions. GraphQL has built-in scalar types such as Int, Float, String, Boolean, and ID (which represents a unique identifier). Additionally, a user is able to create his own types, like a Director type created on the screen.
The next element of GraphQL are queries. They must be part of our schema. Queries are built from elements such as name, parameters (which are optional), and return type, respectively. Then we can see an example of such a query when used with GraphiQL. We can immediately notice that the structure of our query is identical to the structure of the response received from the server component. We will come back to the method of implementation and its use in practice. Passing a single set of arguments is one of the disadvantages of systems like REST. But in GraphQL, every field and nested object can get its own set of arguments, making GraphQL a complete replacement for making multiple GraphQL API fetches. You don’t have to implement data transformations on every client separately, instead of that you are able to pass arguments into scalar fields, you do that once on the server-side.
The next component that we can use in our queries is fragmented. Fragments are reusable units that allow the user to create sets of fields and after that add them to the queries. In this example query, we can see what the use of fragments in GraphQL looks like. It’s not difficult to imagine that in the application we will want to use a query, where some of the required fields will be repeated, in which case fragments will come to the rescue. To split complicated application data requirements into smaller chunks, we'll use fragments, especially when we need to combine lots of UI components into one initial data fetch.
Ok, we already know what data download looks like, but as users, we want to create, modify and delete such data. For these scenarios, we should use mutations. They are defined and used similarly to regular queries. Here you can see mutation examples, how to create, update and delete the data included in the GraphQL schema. Now, take a closer look at how we can use mutation to update data on the server. For this purpose, we run the appropriate function, provided in the GraphQL schema, give it the necessary arguments and after starting the mutation, we check the response from the server. Depending on the implementation, we should receive the appropriate response code and data.
As you may have noticed, in one of the queries, while we were discussing „fragments" of the GraphlQL, we had the possibility to retrieve the data of a "movie" object and at the same time extract the data on the director who created this movie. But, how was this possible since we had only used one endpoint? Well, for this purpose we created a component called "resolver". Resolver is a function or method, defined in the API schema. A resolver can return an object, a scalar value, or a promise. In the first case, the property of the returned object is resolved. In the second scenario, execution ends. In case the resolver returns null, execution will stop, immediately. Resolver functions can accept four arguments: Parent – It stands for the return value of the resolver for this field’s parent. Args – All GraphQL arguments are included in this object. Context – This object is shared across all resolvers that execute for a particular operation. Info – Contains information about the execution state of the operation. In GraphQL, each graphql query goes through three stages: parsing, validation, and execution. Parsing makes the query into an abstract syntax tree. In turn, validation checks the created AST against the schema definition. Lastly, execution is the process of going through an AST from the main node (usually a query), executing the required resolvers, and returning a response. This is where, in the "execution" phase, we need resolvers.
Ok, so now that we've seen how it works, let’s summarize. As you can see there are a lot of pros and cons of GraphQL. Let’s briefly talk about them. - For sure implementing GraphQL will be good for complex systems. Also, when we migrate from monoliths to microservices, GraphQL can improve communication between parts of the system, by hiding the complexity and merging it into one graphQL schema. - This is probably the biggest difference between GraphQL and REST. In GraphQL we have only one endpoint that handles all requests. - User is able to precisely define what data is needed in the request. - Unlike REST, in GraphQL additional validation for data is not needed. It will happen automatically if the user fetches the data with the use of resolvers. - Here is another advantage over REST, documentation is generated automatically. So there is no need to use libraries like Swagger. - GraphQL eliminates the need for versioning, by deprecating APIs on a field level. Aging fields can be removed from the schema later, without impacting the existing queries. GraphQL enables that, by creating a uniform web API across the entire application, that isn’t limited by a specific storage engine. - In this approach, we have one additional operation called subscription. It is used to send notifications automatically, to the awaiting client.
As always, there are no silver bullets. If an application needs to handle a lot of complex queries, performance issues may appear. This is because more of the processing is handled by the server. In scenarios like this, it might be better to use REST over GraphQL.
The next drawback. If the application is rather small and we expect that we will handle only a few simple requests we will not benefit from using GraphQL. It is more complicated to implement a simplified cache with GraphQL than implementing it in REST. Another one could be that there is no built-in support for sending or receiving files, so we need to add an external library, to enable it. Last but not least, knowledge of the schema definition language, is necessary to fully benefit from using GraphQL. Even writing a simple query, seems to be initially more difficult, than in REST.
I feel like we have already discussed some differences between GraphQL and REST principles, so let’s put them together. Currently, on the market, REST is the most commonly used architectural pattern, however, GraphQL is gaining a lot of popularity. In the decision process, while designing the architecture of our layered system, it is good to know, what are the differences between these two solutions. There are no objectively better and worse solutions, there are only better or worse, for a given project.
Finally, we can summarize where using GraphQL will be most beneficial. For sure in all devices like smartphones, smartwatches, or IoT devices, which are more sensitive to fluctuations in performance. What is more, all cases when data is retrieved from multiple servers, APIs, third-party tools will work better when combined all together into GraphQL. And also since GraphQL was developed by Facebook engineers, it’s obvious that all kinds of social networking platforms, where nested data needs to be fetched in a single call, will perform better with GraphQL. So, knowing all of it, we can say that GraphQL will be perfect in case of short life-cycle applications, where we don’t yet have the knowledge, of what and how we are going to share data. During the development of an application, it will be easier to modify such contracts between clients and servers with GraphQL. In the case of more complex infrastructure, REST API may turn out to be difficult to implement, and despite its apparent simplicity, requires knowledge and experience to get it right. If designed badly, problems will multiply. However, if we do it properly, then we will gain full control over the optimization on the server-side, and we can also deal well, with the performance, using typical HTTP tools. Additionally, GraphQL is prepared for communication only using JSON, which may limit us in some cases. REST API, as a more universal approach, does not have such limitations.
Thank you for watching. I hope it was interesting to you, and it encouraged you to learn more about GraphQL. Remember to subscribe to our channel and see you soon in the next expert zone.