GraphQL concept introduction

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, as one of Facebook’s three front-end carriages (the other two are Relay and React, which can be seamlessly integrated), has been around for a while, but surprisingly few people have actually used it. As of the end of 2018, according to Stateofjs, Although only 1/5 developers have used it, a whopping 62.5% say they have and would like to try 😂. I’m going to write a series of articles about GraphQL and how it feels to use GraphQL on the front and back end, and fill in the holes.

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

1. What is GraphQL

Here’s what the official said:

GraphQL is both a query language for the API and a runtime for your data queries. GraphQL provides an easy-to-understand set of complete descriptions of the data in your API, enabling a client to get exactly what it needs without any redundancy, making it easier for the API to evolve over time, and for building powerful developer tools.

Let me summarize:

First, GraphQL is a query language similar to the Restful standard. They have similar levels of functionality (see picture below), but in practical and conceptual terms, they are completely different.

Restful advocates that “all data is treated as a resource.” Ideally, different requests have a unique ID. Different data actions correspond to different HTTP methods.

GraphQL insists that “all data is treated as data (tree)”, different request content will correspond to the same HTTP address, will correspond to the same HTTP method (POST). The different actions are determined by the operator. The overall experience will be more like an SQL Shell, asking for whatever you need and not shoving it down your throat if you don’t need it.

Like Restful, they are only standards, and their implementation varies from product to product, and it is normal to not fully implement all features. But the main functionality and features are present in all implementations. The other two have similar language support, and common languages can have corresponding implementations.

I will compare the differences between the two in more detail. Since Restful is a more general standard, I will not go into the details of Restful. If you are not familiar with Restful standards, it is best to have a look at them before continuing to understand them better.

2. GraphQL vs. Restful data operations

2.1 the query

Restful advocates that all data is treated as a resource, which means you’ll need to request different data multiple times. For example, for a spA-type personal blog like mine, you’ll probably request something like this when you enter the home page (purely hypothetical, not real) :

// Some configuration information, such as configuration items, site titles, etc
https://example.com/config/

// Side TAB bar
https://example.com/tags/

// Side file bar
https://example.com/archives/

// Bulletin information bar
https://example.com/billboard/

// A list of articles
https://example.com/articles/
Copy the code

This is the amount of information that a one-page blog like this would have to request as soon as it hits the home page. Imagine how many requests it would have if it were a highly concurrent, complex site.

But for those words in GraphQL, you only need to ask once, for example:

query {
  config: {
    key,
    value,
  }

  tags: {
    name,
  }

  archives: {
    name,
  }

  billboard

  articles {
    id,
    name,
    description,
    tags: {
      name,
    },
  }
}
Copy the code

The interface then returns something like 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 the code

You can see that the interface returns a JSON data that is exactly what you requested and the field. You can build your own tree of what you need to look like, and the back end doesn’t have to write weird interfaces to fill in the implementation conflicts between business and development for each of your specific needs.

Another is that there are situations where Restful requests need to be separated, where events that could have been requested in parallel need to be serialized because of Restful standards.

Let’s say we want to get other similar articles under the category that the current article is associated with and display them next to it.

You might ask:

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

After obtaining the corresponding article classification, request again:

https://example.com/article/?category=graphql&is_recommend=true
Copy the code

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

As for the correlation between data, ordinary SQL foreign keys and association relations can be directly mapped to return subitems. For example, in the first example, tags in articles are generally connected to different tables in the way of data foreign keys. In GraphQL, they can be directly accessed in the way of subtrees.

All query operations are performed with the query operator in GraphQL. You can write an infinite number of different requests without having to request them separately. When you need to request the same content repeatedly, the front-end GraphQL client has automatic cache processing, can the current web page instance only to a certain content request behind once again the content will not directly use the cached information network requests again, of course you also can do it again.

2.2 change

In Restful, we’re used to describing behavior using different HTTP methods, but in GraphQL, we use operators to indicate behavior.

Query refers to the query operation, which corresponds to the SELECT operation in SQL. So what if you want to change it? In GraphQL, mutation was used, corresponding to UPDATE, INSERT and delete in SQL. At first glance it looks like a mess, but in practice it doesn’t feel that way. I can’t really brag about that part, though, because I personally feel it’s more like putting something that was done on the back end into the front end. It is used very much like giving the front end a “back end function”.

* All of the examples below are just demonstrations, not actual writing, which would be more rigorous

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

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

To add an article:

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

The modification operation is similar to adding new ones.

While this may seem sparse and haphazard, it actually gives the developer more freedom. Convenient custom behavior. In addition, it is worth mentioning that before Mutation, after a Mutation operation is called, it will automatically verify the input parameter type in the front-end code, similar to the compilation of static language. If there is an error in the input parameter, it will automatically report an error and indicate the error location to give error information. If there is no problem, the HTTP request changes. The back end verifies it again when it is sent to the back end. I personally like that.

2.3 the subscription

Subscriptions are a prominent feature, and traditional businesses often have similar requirements, but Restful doesn’t cover them. Subscribing in GraphQL is currently not fully supported in most implementations. It basically means that when you subscribe to something in the front end, when the content changes in the back end, the server will actively notify the front end, which will trigger UI logic or operations, etc. Currently it seems that most implementations of this feature are unsupported or not fully supported. And it seems like most of the time you have to rely on long links or polling. Still, it’s very promising, because what it does is allow you to subscribe to arbitrary data rather than having the backend do a dedicated interface for a particular content, as traditional implementations do.

A classic application scenarios such as: when you open an article, this article comments sent a subscription operation, at this time if someone while you see the article on articles such as a new comment or reply, corresponding changes will be by the backend actively pushed to the front, so that you can live to see the latest comments.

Subscriptions correspond to the Subscription operator in GraphQL. Similar to mutation notation.

If anyone knows more, please feel free to comment. I am not familiar with this area and do not understand it deeply.

2.4 the paging

Traditional Restful uses spacing paging, that is, after setting a fixed spacing, you can calculate the content of any page based on the spacing size and the page number of the current page.

GraphQL is a bit more of a pointer pagination, where whatever element you’re currently on, you’re pointing to that point and asking for a given amount forward or backward. It has the disadvantage of not being able to deduce the contents of any page from the current position like spacing, but it has the advantage that you don’t care about any other information at all, always using the current point as a pointer to seamlessly scale back and forth as you like.

Restful mode is more consistent with the traditional indexed interactive experience on the desktop. GraphQL’s approach is more convenient in more modern Web interactions such as waterfall streams, applets, and sliding auto-loading in native applications.

PS: GraphQL is also compatible with spaced paging, but I won’t go into detail in this article.

3. GraphQL’s relative Restful advantages

3.1 Interface Version Management

In Restful, standard management is declared with different link entries, such as:

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

There are no different entry points in the GraphQL world, and interface version iteration can be seamless because the different query content itself is issued by the front end, which is not limited by the back end.

3.2 Clearer and transparent data structures and more robust interfaces

As I mentioned above, in practice, both the front and back end have strongly typed parameter validation, so it is relatively easy to sense errors, and! It greatly reduces the potential for other hidden errors. For example, a logic error occurs when the back end changes something in an interface and forgets to tell the front end. None of these extremely easy problems are likely to occur in GraphQL.

3.3 Better caching system

As I mentioned in the [Query] section above, the GraphQL client comes with a caching system to further save request consumption. You can turn this feature off if you don’t want it.

3.4 Front-end friendly development experience

As mentioned above, what you need can be decided by the front end. In businesses that require strong associations, GraphQL can find associations indefinitely, eliminating a lot of asynchronous syntax on the front end and avoiding Promise or Callback hell. In addition, in some backend languages such as Python, fields are commonly named as underscores by convention. In Javascript, however, the more common naming method is the camel’s back, which, because the data is returned from the back end, inevitably leads to ugly front-end code with a variety of different naming methods; You might say, we can do data name cleaning after we get the data, but this would definitely increase the time complexity and reduce the maintainability of the code, which is not desirable by any means. But!!! This problem doesn’t exist in GraphQL (or, more precisely, in the stack I’m using). Because in Graphene, it will automatically convert the returned data in the naming mode, hump is used in the front end, and underline is used in the back end to avoid interference.

3.5 Rigorous development experience and more obvious error reporting mechanism

Since the input and output of GraphQL are defined based on Schema, the calling method and query are strongly typed input and output, which can locate the cause and location of errors more efficiently. If the client operation passes the wrong parameter, it will not even send a request to the client to report the error and explain the reason. If the parameter is passed correctly but the server fails, everything else in the same query is returned correctly, except for the error which is left blank and a message field indicating the cause and location of the error.

Github’s GraphQL V4 API shows an error in the user query, but the search data returns normally.

3.5 More convenient debugging process

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

(Specific SQL statements are not shown for security reasons)

3.6 Code is documentation

As you can see from the above picture, GraphQL provides a dynamic interactive window in a web page that provides GraphQL auto-completion, formatted query statements, and history operations. One of the most powerful is its interface documentation. Code-as-document information is very useful.

Here you can see directly what the entire tree structure looks like, see clear class inheritance relationships (not captured), see detailed descriptions of different queries and parameter types, etc.

4. GraphQL’s disadvantages

Whatever it is, there must be something better than something else. GraphQL has a number of advantages for developing a modern, complex Web service or site, but it also has significant disadvantages.

4.1 Performance Cost

Because GraphQL has its own hierarchical query, it is easy to have redundant queries, causing unnecessary query overhead.

Of course, this problem also depends a lot on the backend framework you use, but I recommend a good article about Django: the N+1 problem

4.2 Development without prompting

Although it does provide a very powerful in-page debugging window. But in real development, the front end will write various statements in the IDE without any hint, and it is easy to misspell, because the editor does not recognize what you are writing, it treats it as plain text at best, and it does not format the content, so it can be a little uncomfortable in development.

4.3 Interface test tools are relatively few

Because Restful has a long history and is widely used, almost all interface tools on the market can support Restful queries, but GraphQL cannot. The only thing I know about Insomnia is that it doesn’t support documentation very well. (Of course, the framework already provides excellent debugging tools.)

5. Which GraphQL client is strong

One is Facebook’s own Relay and the other is Apollo, which is supported by the community.

Relay is more expensive to learn, just like when you’ve learned the basics of React and can write simple pages with React, you’re suddenly asked to learn the Redux concept. You need to learn a new way of managing data.

Apollo is much friendlier, with jSX-style block writing and Axios request functionality, as well as relay-style query writing, making it much easier to learn. Native state management can completely replace Redux.

End of 6.

Both are standards and design guidelines; It cannot be said objectively that one is better than the other. But personally I can see GraphQL has quite a few advantages over Restful. After all, GraphQL itself is much younger than Restful, and it was created to solve most, if not all, of the legacy problems of its predecessors.

The most important thing is that they are completely compatible. Nobody interferes with nobody.

Finally, find more links to further reading and learning:

  • GraphQL – Chinese official website
  • How to GraphQL – a learning website
  • Rest VS GraphQL
  • GraphQL or REST
  • Is GraphQL a REST killer?