Hi, Habr!
A brief insight into the GraphQL query language will serve you the
book of Alex Banks and Eva Porsello, which we translated into translation a couple of days ago. The book of the same authors about
React and Redux has become a real bestseller (waiting for the 5th edition of the printing house). By the way, thanks to everyone who pointed out the inaccuracies in the code and terms;) we did the book on such a rapidly aging technology too quickly.
The author of today's article, Robin Viruh, is also working on a book about GraphQL and libraries for this language, and in this article he briefly explains the merits and characteristics of GraphQL as an alternative to REST

')
When it comes to network requests between client and server applications, REST is often chosen as the bridge between the client and server worlds. In REST, everything evolves around the idea of ​​“we need resources available via URLs”. You can read a resource using an
HTTP GET
, create a resource using an
HTTP POST
request, update it, and delete it using
HTTP PUT
and
DELETE
requests. These operations are called CRUD (Create, Read, Update, Delete). The resource can be any content received from authors, users or taken from articles. When using REST, the data transfer format is not strictly specified, but most often JSON is used for this purpose. In the end, REST provides communication between applications over the usual HTTP protocol using URLs and HTTP methods.
Although, for a long time, REST remained the de facto standard, in recent years another technology that has been developed in Facebook has begun to gain popularity: it is called GraphQL. This article - an introduction to GraphQL, talks about the advantages and disadvantages of this query language.
What is GraphQL?Before diving into the discussion of the advantages and disadvantages of GraphQL, let's first answer the following question: what is GraphQL? GraphQL is a free
query language created by Facebook in 2012. Even before the product was submitted to open-source, the language was already used on Facebook as an intracorporate technology for working with mobile applications. Why precisely with mobile applications? GraphQL was developed as an alternative to the typical REST architecture. It allows the client to only request the desired data - no more, no less. The client is responsible for everything, that is, you. In the REST architecture, difficulties arise in this case, since it is the database interface that determines what information will be available to each resource for each URL. Data sampling is not requested in the client part. Therefore, in any case, the frontend should request all information about the resource, even if it needs only a part of this data. This problem is called “repacking.” In the worst case scenario, the client application has to read not even one, but a multitude of resources, for which it is necessary to refer to many network requests. This leads not only to re-sampling, but also to avalanche-like requests over the network. However, having such a query language as GraphQL, used not only on the server side, but also on the client side, the client itself decides what data it needs - and for this it sends only one request to the server. When Facebook developed mobile applications using the GraphQL language, it was possible to drastically reduce the network load, since much less data was transmitted over it.
Facebook has laid out in free access the GraphQL specification and its reference implementation in JavaScript. Since then, this specification has been implemented in many other major programming languages. In addition, the ecosystem that has developed around GraphQL, grows not only horizontally, spreading to other programming languages, but also vertically (libraries, such as Apollo, Relay) are built on top of GraphQL.
GraphQL provides the following types of operations: request (read), change (write) or subscription (continuous read). Any of these operations is just a string that must be assembled according to the GraphQL query language specification. As soon as such GraphQL operation comes into the database application from the client application, it can be interpreted in comparison with the entire GraphQL scheme located on the backend and resolved for the client application using the available data. GraphQL works with equal success with any network layer (which is often organized via HTTP), as well as with any payload format (often JSON). Also, he absolutely does not care about the application architecture (which in most cases consists of the client part and the database interface). This is just a query language.
As you can see, the request is already asking for a variety of resources (author, article), which in GraphQL are called fields, and only a specific set of nested fields for these fields (name, urlSlug for the article), although other things can be provided in the GraphQL data scheme itself. information (for example, for the article - description, release date). While in the REST architecture, we would need at least two cascading queries to extract the “author” entity and articles of this author, GraphQL solves this problem in one query. In addition, when a query selects only the required fields, not the entire entity as a whole.
This is the essence of GraphQL. In the case when the server application provides the GraphQL scheme, in which it defines all the available data with its own hierarchy and types, the client application requests only the data it needs.
Benefits of GraphQLThe following are the main benefits of using GraphQL in an application.
Declarative data samplingAs you can see, GraphQL uses declarative data sampling in its queries. The client selects the data, their entities, and all the fields between which there are various relationships, and a single query is used for all of this. The client decides which fields it needs for this UI. Often, you can almost talk about UI-oriented data sampling. For example, this is how Airbnb uses GraphQL. In the Airbnb search engine, results are often given for homes, impressions, and other categories specific to a given subject area. To extract all the data at once, a GraphQL query is executed, picking up only the information that is definitely needed in a particular UI. In the end, the division of responsibility is perfectly organized in GraphQL: the client knows about the data requirements, the server knows about the data structure and how to resolve data from an existing source (be it a database, microservice, third-party API).
No re-sampling when working with GraphQLWhen working with GraphQL re-sampling does not happen. Whereas the mobile client is likely to hit the re-sample using the same API as the web client with the REST-API. And when working with GraphQL, the mobile client and the web client can choose for themselves different groups of fields using the same GraphQL API. Consequently, the mobile client may choose less information, since superfluous information may not be needed on a small screen (unlike a large monitor, from which the web version of the application is viewed). GraphQL minimizes the amount of data transmitted over the network, selectively selecting them and being guided in the first place by the needs of the client application.
GraphQL for React, Angular, Node, etc.GraphQL is a promising solution not only for React developers. Suppose Facebook has done GraphQL, and on the client side, Facebook uses React, in fact, this language is not tied to any solution for the frontend or backend. The GraphQL reference implementation is written in JavaScript, so GraphQL can be combined with Angular, Vue, Express, Hapi, Koa and other JavaScript libraries in the client and server parts. Moreover, this concerns not only the JavaScript ecosystem. GraphQL imitates REST in one aspect, thanks to which it became popular: the GraphQL interface does not depend on the programming language (query language) used to communicate two objects (for example, a client and a server). Therefore, its specification can be reproduced in any programming language.
Who uses GraphQL?Facebook has been using GraphQL since 2012, even before this language has become open source. It is Facebook that is the driving force that is responsible for the development of the GraphQL specification and its reference implementation in the JavaScript language. So, working with GraphQL, you are already standing on the shoulders of giants. However, other well-known companies use this language in their applications. They are investing in the GraphQL ecosystem, since modern applications are in dire need of just such a language. So, you will be supported not only by Facebook, but also by the following companies:
When Facebook developed GraphQL and made it publicly available, other companies that created mobile apps also had similar problems. This is how Netflix created the Falcor project, which can be considered an alternative to GraphQL. That once again confirms that such applications as GraphQL and Falcor are needed for modern applications.
Single source of truthIn GraphQL applications, there is a truth in the last resort: this is a GraphQL scheme. She is the central source in which all available data are described. While the GraphQL scheme is usually defined on the server side, clients can read (request) and write (change) data based on this scheme. Thus, the server application, in essence, provides exhaustive information available on the server, and the client side only requests what is required by formulating queries in GraphQL, or modifies small information fragments, using the changes in GraphQL.
GraphQL follows current trends.GraphQL follows current trends in building applications. You can have only one application on the backend, but it often happens that many different clients use this backend (web client, mobile device, smartwatch ...) and they all depend on the data stored in the backend application. Consequently, GraphQL can help not only make “both worlds” friends, but also satisfy the requirements of each client (connected, for example, using the network, nested data interconnections, sampling only the required data) without the need to create a dedicated API for each type of client.
On the other hand, not a single internal interface can wait for us on the server, but a group of microservices, each of which provides its own specific functionality. The GraphQL scheme is ideally suited for such a case, the structure of which is such that in such GraphQL scheme it is possible to aggregate all sorts of functionality.
How to merge GraphQL schemeDue to crosslinking, it is possible to assemble one scheme from many others. When can you get into this situation? Suppose your backend is implemented using a microservice architecture. Each microservice processes business logic and data related to a specific subject area. Therefore, each microservice can define its own GraphQL scheme. After that, you will need to stitch them in order to assemble one of all the schemes to which the client application will refer. In the end, each microservice can have its own GraphQL terminal, and one GraphQL API gateway will consolidate all the schemes into one global one in order to provide it to client applications.
GraphQL IntrospectionGraphQL Introspection is an opportunity to extract a GraphQL scheme with the GraphQL API. Since the diagram contains all the information about all the data available through the GraphQL API, it can be used with great success for the automatic generation of API documentation. However, the case is not limited to documenting the API; Introspection can also be used to simulate a GraphQL scheme on a client application (for testing purposes) or to extract schemes from a variety of microservices and then merge these schemes.
Strongly typed GraphQLGraphQL is a strongly typed query language written in Graphical Expressive Schema Definition Language (SDL). This language has the same advantages as any strongly typed programming language. It is less error prone, allows validation at compile time, and allows you to rely on integration with supported IDE / editor features such as autocompletion and input support.
GraphQL VersioningGraphQL does not have the API versions we are used to in REST. In REST, it is normal to offer several versions of the same API (for example, api.domain.com/v1/, api.domain.com/v2/), since resources or their structure may change over time. In GraphQL, you can convert APIs to fields that are not recommended at the field level. Consequently, the client receives a warning when it accesses the non-recommended field. After some time, the non-recommended field can be excluded from the scheme, then no other clients will use it. Thus, the GraphQL API can evolve without the need for versioning.
GraphQL Growing EcosystemThe GraphQL Ecosystem is growing. It's not just about integration with editors and IDEs related to the strongly typed nature of GraphQL; for GraphQL as such, there are new full-fledged applications. For example, you can recall Postman, used when working with the REST API, and now for the same purpose, but with GraphQL API, GraphiQL or GraphQL Playground is used. There are also various libraries for you, for example, Gatsby.js, a static website generator for React using GraphQL. For example, Gatsby.js allows you to write a blog engine that fills your blog with content during the build through the GraphQL API. Consequently, you will also have CMS without a client part (for example, GraphCMS) providing content (for a blog) via GraphQL. API. However, not only technological components develop in this area. Like mushrooms, after the rain, GraphQL conferences, meetings and communities are growing, it’s also easy to find newsletters and podcasts on it.
If I switch to GraphQL, do I go all-in?Adding GraphQL to the existing technological stack, we, of course, do not go all-in. Migrating from a monolithic backend application to a microservice architecture, the whole point is to substitute the GraphQL API for newly-made microservices. After all, in the presence of multiple microservices, you and your team can safely implement the GraphQL gateway, stitching schemes and consolidating them into one global scheme. But the API gateway can be used not only with microservices, but also with a monolithic REST application. This is how you can combine all your APIs in one gateway and migrate to GraphQL step by step.
GraphQL DisadvantagesNext, we discuss some of the drawbacks associated with using GraphQL.
GraphQL query complexitySometimes GraphQL is used incorrectly, trying to replace the database on the server side with it. No, that will not do. GraphQL is just a query language. When a server-side query needs to be resolved with data, there will usually be an implementation independent of GraphQL that provides access to the database. GraphQL in this case is indifferent. Moreover, GraphQL does not eliminate any performance bottlenecks when you need to address multiple fields in the same request (authors, articles, comments). Regardless of the architecture in which the query was made - RESTful or GraphQL, you still need to extract various fields from the source.
Thus, we will have a problem if the client sends a bunch of requests to a set of nested fields at once. Often, client-side developers do not know how many different database queries have to be processed in the server application if mass requests to data begin. It is precisely in such cases that a mechanism is needed (for example, the maximum depth of requests, weighting of the complexity of requests, avoiding recursion, constant requests) to prevent the flow of too expensive requests from the client.
Speed ​​limit in graphqlAnother problem is the speed limit. While in REST it is relatively simple to say “no more than so many requests per day are allowed”, it is difficult to formulate such an instruction for individual GraphQL operations, since there are not only “costly” and “non-costly” operations, but also a lot of intermediate gradations. For such cases, companies that
provide GraphQL public APIs offer their own speed limit calculations , often reducible to the aforementioned maximum depths of queries and weighting the complexity of queries.
GraphQL CachingWhen working with GraphQL, the implementation of the simplified cache is much more complicated than in REST. Working with REST, we access resources by URL and, therefore, we can organize caching at the resource level, since the URL of a resource can serve as its identifier. This is complicated in GraphQL, since all queries can turn out to be different, even though they all operate on the same object. In one request, you can request the name of the author, and in the next - not only the name of the author, but also his email address. For such cases, you will need a more delicate cache at the field level, but it's not so easy to implement it. However, most libraries built on top of GraphQL offer such caching mechanisms right out of the box.
Why not REST?GraphQL – REST, . REST – GraphQL, REST?
REST URL , . «», id, , id. GraphQL , . , , , GraphQL , .
, REST. Airbnb. , . REST-, REST- . , , GraphQL API, GraphQL, (, ), (., ).
, GraphQL ; , , , . GraphQL – Facebook , -.
, , REST – . , GraphQL. , GraphQL, - .