Getting started with GraphQL concepts

Getting started with GraphQL concepts

Getting started with GraphQL concepts

Restful is Great! But GraphQL is Better. - My Humble Opinion.

GraphQL will do to REST what JSON did to XML. - Samer Buna from Quora

GraphQL is one of the three front-end carriages of Facebook (the other two are Relay and React, and the three can be seamlessly combined). It has been proposed for some time, but surprisingly few people have actually used it. As of the end of 2018, according to According to the data of Stateofjs , although only 1/5 of the developers have used it, as many as 62.5% of them said they have heard it and want to try it. Sure enough, salted fish is the mainstream; next I will focus on the front-end and back-end applications of GraphQL Published a series of articles to introduce GraphQL and its use experience, by the way, fill in the hole.

This series will use Python + Django + Graphene as the backend server. Apollo acts as the front-end client.

1. What is GraphQL

The official said:

GraphQL is not only a query language for APIs, but also a runtime that satisfies your data queries. GraphQL provides a set of easy-to-understand and complete descriptions for the data in your API, so that the client can accurately obtain the data it needs without any redundancy. It also makes it easier for the API to evolve over time. Can be used to build powerful developer tools.

Let me summarize:

First of all, GraphQL is a query language similar to the Restful standard. Their functional levels are similar (as shown in the figure below), but in terms of practical applications and concepts, they are two completely different forms.

Restful advocates that "all data is treated as a resource". In an ideal situation: different request content corresponds to a unique ID. Different data actions correspond to different HTTP methods.

GraphQL advocates that "all data is treated as data (tree-shaped)", and different request content will correspond to the same HTTP address and the same HTTP method (POST). The different actions are determined by the operator. Its overall experience will be more like a SQL Shell, you can request whatever you need, and it won't force you into the content you don't need.

Similar to Restful, they are only a standard, and their specific implementations of different products are different, and it is normal that all features are not fully implemented. But the main functions and features are found in all implementations. In addition, the different language support of the two is basically the same, and common languages can have corresponding implementations.

Below I will make a relatively detailed comparison of the differences between the two. Since Restful is a relatively general standard, I will not introduce the specific content of Restful in detail below. If you are not familiar with the Restful standard, it is best to understand it before continuing. For better understanding.

2. Data operation comparison between GraphQL and Restful

2.1 Query

Restful advocates that all data is regarded as a resource, which means that you will need to request multiple times for different data. For example, for a personal blog of SPA type like me, you will probably request these content when you enter the homepage (pure hypothesis, not actual Happening):

//Some configuration information: such as configuration items, site titles, etc. https://example.com/config/ //tab bar on the side https://example.com/tags/ //Archive column on the side https://example.com/archives/ //Announcement Information Bar https://example.com/billboard/ //list of articles https://example.com/articles/ Copy code

Such a single-page blog must request so much information when it enters the homepage. Imagine how large the number of requests would be if it were a highly concurrent and complex content structure.

But these words in GraphQL, you only need to request once, such as:

query { config: { key, value, } tags: { name, } archives: { name, } billboard articles { id, name, description, tags: { name, }, } } Copy code

Then, the return content of the interface will be similar to this:

data: { config : [ { key : 'title' , value : 'xxx' , }, { key : 'slogan' , value : 'xxx' , }, ], tags : [ 'Go' , 'Java' , 'Javascript' ], archives : [ '2011' , '2012' , '2013' ], billboard : 'XXX XXX XXX' , articles : [ { id : 1 , name : 'some name' , description : 'XX XX XXX' , tags : [ 'tag1' , 'tag2' ], }, { id : 2 , name : 'some name' , description : 'XX XX XXX' , tags : [ 'tag1' , 'tag2' ], }, { id : 3 , name : 'some name' , description : 'XX XX XXX' , tags : [ 'tag1' , 'tag2' ], }, ], } Copy code

You can see that the return content of the interface is a JSON data accurately returned according to the content and fields you requested. And retain the structure you requested. What kind of tree structure you need can be constructed by yourself. The back end does not need to write some strange interfaces for each of your specific needs to fill the business. Implementation conflicts with development.

Another is that in some scenarios, if you request in the way of Restful, you will need to separate the requests, that is, events that can be requested in parallel need to be serialized because of the Restful standard.

For example, we want to get other similar articles under the category associated with the current article, and then display them on the side.

You may request first:

https://example.com/article/1/Copy code

After obtaining the corresponding article classification, request:

https://example.com/article/?category=graphql&is_recommend=trueCopy code

Then you can render the complete page content. These are all avoidable in GraphQL.

For the association between data, ordinary SQL foreign keys and association relationships can also be directly mapped into sub-items to return. For example, the tags in articles in the above example 1 are generally connected to different tables in the form of data foreign keys. , It can be used directly in GraphQL as a subtree.

All query operations are in GraphQL with operators

query
carried out. There can be countless different request content, no need to request multiple times separately. In the case that you need to request the same content multiple times, the current front-end GraphQL client has automatic caching processing, which can achieve that the current web page instance only requests a certain content once and then it will not send out the network when the content is requested again later. The cached information is used directly when requesting, of course, you can do it again if you want to issue it again.

2.2 Changes

In Restful, we are used to describing behavior with different HTTP methods, but in GraphQL, we use operators to indicate behavior.

Above

query
Refers to the query operation, corresponding to the SQL
select
operating. What if you want to modify it? In GraphQL we use
mutation
, Which corresponds to SQL
update
,
insert
and
delete
. At first glance, there is a sense of chaos, but it does not feel like this in actual use. Although I really can't blow this part, because this part I personally feel that it is more like putting the content that was originally made on the back end to the front end. Its use is very much like giving a "back-end function" to the front-end.

* All the following examples are just demonstrations, not the actual writing, the actual writing will be more rigorous

If we want to delete an article, we can do this:

mutation { deleteArticle(id: "some ID") {} } Copy code

If you want to add an article:

mutation { createArticle( title: "some title", content: "some content", ) { id, title, content, } } Copy code

The modification operation is similar to the addition, so I won t repeat it.

Although it looks relatively sparse and seems very random, these operations actually give developers more freedom. Convenient for customized behavior. Another point worth mentioning is that before actually doing Mutation, after calling a Mutation operation, it will automatically check the input parameter type in the front-end code, similar to the compilation of static language, if the input parameter is wrong, it will Automatically report an error and prompt the error location to give an error message. If there is no problem, the HTTP request change operation will be sent. When it is transmitted to the backend, it will be checked again by the backend. I personally like this very much.

2.3 Subscription

Subscription is a relatively prominent feature, and traditional businesses often have similar requirements, but Restful does not manage it. Subscription to this feature in GraphQL currently seems to be incompletely supported in most implementations. The general meaning is that when you subscribe to a certain content in the front-end, when the content of the back-end changes, the server will actively notify the front-end, which will trigger UI logic or operations. At present, it seems that most implementations of this part of the feature are not supported or not fully supported. And it seems that most situations can only rely on long links or polling to do it. Nevertheless, it is very exciting, because what it does is to allow you to subscribe to arbitrary data instead of letting the back end make a dedicated interface for a particular content as in the traditional implementation.

A classic application scenario such as: When you open an article, send a subscription operation to the comment area of the article. At this time, if someone adds a comment to the article or responds to a comment while you are reading the article, the corresponding The changes will be actively pushed from the backend to the frontend, so that you can see the latest comment content in real time.

Subscription corresponds to GraphQL

subscription
Operator. versus
mutation
The writing is similar.

If anyone knows better, please feel free to enlighten me. I am not very familiar with this area and have no in-depth understanding.

2.4 Paging

The traditional Restful uses spacing paging, that is, after a fixed spacing is set, the content of any page can be calculated from the spacing size and the current page number.

GraphQL is relatively more advocating pointer paging, that is, no matter which element you are currently on, use the current point as the pointer, and request a given amount forward or backward. One of its disadvantages is that it cannot calculate the content of any page at the current position like the spacing formula, but its advantage is that you don't care about any other information at all, and you can always use the current point as a pointer to move forward or backward at will. Seam expansion and contraction.

Restful is more in line with the traditional indexed interactive experience habits of the desktop. However, methods like GraphQL are more convenient in more modern web interactions, such as waterfalls, applets, and native applications.

PS: GraphQL can also be compatible with spaced paging, the specific implementation will be discussed later, and I will not go into details in this article.

3. GraphQL's advantages over Restful

3.1 Interface version management

The standard management method in Restful is declared in different link entries, such as:

https://v1.example.com/ https://example.com/v1/ Copy code

In the world of GraphQL, there are no different entry points. Interface version iteration can be seamlessly transitioned, because different query content itself is issued by the front-end, and the front-end is not restricted by the back-end.

3.2 Clearer and more transparent data structure and more robust interface

As I said above, in actual use, the front and back ends will have strong type parameter verification, so relatively speaking, it is easier to perceive errors, and! It greatly reduces the possibility of other hidden errors. For example, if the back end changes something in an interface and forgets to inform the front end, it causes a logical error. These extremely prone problems are unlikely to appear in GraphQL.

3.3 A better cache system

As I mentioned in the [Query] section above, GraphQL's client has its own caching system, which can further save request consumption. You can turn off this feature if you don't want it.

3.4 Front-end friendly development experience

As mentioned above, what you need can be determined by the front end. In the business that requires strong correlation, GraphQL can find the relationship infinitely, save a lot of asynchronous syntax on the front end, and greatly avoid the problem of Promise or Callback hell. In addition, in some back-end languages, such as Python, fields are usually underscore naming conventions. But in Javascript, camel case naming is more commonly used. Since the data is returned by the backend, the front-end code becomes ugly and mixed with various naming methods. Maybe you would say, We can perform data naming cleaning after we get the data, but this will undoubtedly increase the time complexity and reduce the maintainability of the code, which is not desirable anyway. but! This problem does not exist in GraphQL (strictly speaking, in the technology stack I use). Because in Graphene, it automatically converts the naming of the returned data. The front end uses hump and the back end uses underscores without interference.

3.5 Rigorous development experience and more obvious error reporting mechanism

Since GraphQL's input and output are defined based on Schema, the calling method and query are all strongly typed input and output, which can locate the cause and location of the error more efficiently. If the parameters passed by the client operation are incorrect, it will report an error on the client and explain the reason without even sending a request. If the parameter is passed correctly but the server has an error, other content can be returned correctly in the same query, and only the error content will be empty and will provide a

message
The field explains the reason and location of the error.

The picture below shows the GraphQL v4 API of Github . You can see that the user query made an error but

search
The data is returned normally.

3.5 More convenient debugging process

In addition to the very detailed error report above, you can even perform dynamic debugging directly in the browser; the following figure is a Debug query of a project of my own. You can check how the SQL statement of the current query is written, how long it took, and whether It takes too long, what parameters to bring, transaction ID, transaction status and other various information.

(Due to security reasons, the specific SQL statement will not be shown)

3.6 Code is Document

From the above picture, you can see that when GraphQL is used, it will provide a dynamic interactive window in the web page, providing GraphQL automatic completion, formatted query statements, historical operations and other information. One of the most powerful is its interface documentation. Code as documented information is very useful.

Here you can directly see how the entire tree structure is, you can also see the clear class inheritance relationship (not shown in the figure), and you can also see the detailed description of different query content and parameter types.

4. Disadvantages of GraphQL

No matter what, there must be advantages and disadvantages in comparison between two things. For developing a modern and complex web service or site, GraphQL has a bunch of advantages, but it also has obvious disadvantages.

4.1 Performance overhead

Since GraphQL comes with hierarchical queries, redundant queries are prone to appear, causing unnecessary query overhead.

Of course, this problem is largely related to the back-end framework you use. I recommend a well-written article about Django: N+1 problem

4.2 Silent development

Although it provides a very powerful debugging window within the webpage. But in actual development, the front end will not have any prompts when writing various statements in the IDE, and it is also easy to misspelling, because the editor cannot recognize what you are writing at all, and it treats it as pure at best. The text does not format the content, so it will be a little uncomfortable at this point in development.

4.3 Relatively few interface test tools

Restful has a long history and is universally applicable, so basically all interface tools on the market can support Restful queries, but GraphQL does not. At present, all I know is supported by Insomnia, but some functions of the document are not well supported. (Of course the framework itself already provides great debugging tools)

5. Which GraphQL client is better?

This only depends on your skills. There are almost two dominant players on the market. One is Facebook's own Relay, and the other is Apollo, which is supported by the community.

Relay learning costs will be higher, just like you just finished learning the basics of React, and you will write some simple pages in React, and suddenly you are asked to learn Redux concepts. Need to learn a new set of data management methods.

In comparison, Apollo will be more friendly. It supports JSX-style block writing, and it also supports directly using its request function as Axios, and it can also be compatible with Relay-style query writing. The learning threshold is relatively low. The built-in local state management can completely replace Redux. Really. One of the best (Axios + Redux)

6. End

Both are standards and design guidelines; it cannot be said objectively that whoever is better than others. But personally, I can see a lot of advantages of GraphQL over Restful. After all, GraphQL itself is younger than Restful, and his appearance must be to solve the legacy problems of the previous generation, not all but most.

The most important thing is that the two are fully compatible. No one interferes with anyone.

Finally, throw more links to expand reading and learning: