What is GraphQL? The first time you see this term, it’s reminiscent of SQL, the database query language. But essentially, these are two completely different things, and GraphQL is defined in the official documentation as follows:

GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data.

GraphQL is both an API query language and a server-side implementation. However, GraphQL is not just about making a database-like query language in the FIELD of API. Its birth also involves a change of thought in API design.

Problems with the REST pattern

Often, a new technology is born when a new trend is emerging in the field it is in, or when the existing technology is unable to cope with the new trend. In recent years, several trends in THE API space have become more noteworthy:

The first is the increasing number of mobile applications, and the contradiction between the low performance of mobile applications itself, requiring a more efficient data loading process.

Furthermore, to meet the need for rapid development and rapid addition of features on the client and front end, the API must be able to expand rapidly.

Thirdly, a variety of different front-end frameworks and platforms emerge endlessly. In the face of numerous front-end frameworks and even the sharing of APIS between front-end and client, back-end API services can provide data on demand, which will affect interface reuse and development efficiency.

The REST pattern, now widely used in the API world, presents problems with the increasingly complex client-server interactions described above:

The first is poor interface flexibility. Due to coarse design interface granularity or historical reasons, sometimes there are fields in the interface that are not needed for current data interaction, resulting in useless and redundant data. On the other hand, sometimes the front end needs a piece of data that requires manual access to multiple interfaces to get the complete data.

Second, the interface operation process is cumbersome. Recall the process of front-end data acquisition, usually we need to construct HTTP requests first, and then receive and parse the server response. Sometimes, another local data dump of received or processed data is performed before the UI presentation.

Third, with the expansion of client functions, the server continues to add interfaces. Maintaining numerous interfaces in this way not only costs a lot to maintain on the server side, but also can’t provide data on demand, hindering rapid iteration and expansion of the client side.

And the REST pattern is essentially based on the HTTP protocol, which makes it easy for Web developers to understand and learn, but also prevents it from having the flexibility to choose network protocols to solve problems.

GraphQL solution

Facebook came up with a solution to this problem — GraphQL:

GraphQL is both an API query language and a server-side implementation, so GraphQL itself is made up of two parts, which Facebook has opened source separately:

  • Language standard: Open Web Foundation Agreement (OWFa) V1.0
  • Graphql. js, client tool Relay: MIT protocol

Let’s take a look at GraphQL’s features one by one:

Declarative data acquisition

As you can see in the figure below, declarative data queries bring the exact return of the interface, and the server returns JSON data with the same structure in the data query format, with real flexibility for the client:

In addition, this method of data acquisition also leads to a simpler data query process. According to GraphQL, the client only needs to describe the query structure to initiate the query, and then use the server response data for UI presentation. The GraphQL client assists in constructing requests and dumping data.

A service exposes only one GraphQL layer

The diagram above shows the basic architecture of a GraphQL application, where the client only interacts API with the GraphQL layer, which then accesses various data sources. In this way, the GraphQL layer allows clients to fetch as much data as they want from the data source, without having to specify the interface.

Transport layer independent, database technology independent

For example, we can choose mobile device-friendly protocols to minimize the amount of data transferred over the network and optimize applications at the network protocol level.

GraphQL Access Overview

Since GraphQL has so many advantages, how do you access it? In general, there are three ways to access:

GraphQL service directly connected to the database

Even with the simplest service configuration, working directly with the database can reduce performance costs in the middle.

GraphQL layer that integrates existing services

This configuration is suitable for the transformation of the old service, especially when third-party services are involved, the original interface can still be used for interaction.

A hybrid pattern of directly connected databases and integrated services

A mixture of the first two:

GraphQL core concept analysis

GraphQL is characterized by declarative API Schema. GraphQL Schema is a declarative query specification (can be considered as a query protocol between server and client). It is mainly composed of two parts:

  • The type system
  • Write syntax: SDL (View Definition Language)

GraphQL’s type system contains data types common to all programming languages, as described in the specification documentation.

Here’s a quick look at GraphQL’s SDL syntax:

Define the API Schema

The definition of custom types is mainly done on the server side. The syntax is as follows:

typeType name {field name: type}Copy the code

In addition, GraphQL has special root types such as Query, Mutation, and Subscription that define API schemas. We can define a user:

type User {
    id: Int!
    name: String
}
Copy the code

Then define several API schemas for data manipulation:

typeQuery {// Schema user(id: Int!) : User // Pass in an ID and return the specific User}typeMutation {// Schema createUser for manipulating data (// automatically create a User name: String): User}typeSubscription {// Schema userChanged: User}Copy the code

Data manipulation

With these defined API schemas, we can initiate data operations from here. GraphQL also provides Query, Mutation, and Subscription data operations. Simply put, a Query is a basic Query that gets data. Mutation supports adding, deleting, and modifying data. Subscription is used to listen for changes in data and push changes to subscribers using protocols such as Websocket.

Based on the user Schema defined above, we can write the following data operations:

Query {user(id:3) {// query user name (id:3)}} mutation {createUser(name: name)"Tom") {// Add a new one named"Tom"User name id}} subscription {userChanged}Copy the code

For these queries, all content after the root field is called the payload of the query. The server returns the payload specified in the data field. For example, the createUser operation returns the following data:

{
  "data": {
    "createUser": {
      "name": "Tom"."id": 9}}}Copy the code

GraphQL ecosystem

With API Schema, we can both specify API functionality and define how clients request data. But this is just a specification. How do you implement the GraphQL specification? Next, we’ll take a look at the GraphQL application development “ecosystem” around the server side, client side, and debugging tools.

Server-side implementation

On the server side, the GraphQL server can be implemented in any language that can build a Web server. In addition to JavaScript, Ruby, Python, Scala, Java, Clojure, Go, and.NET all have implementations for reference.

The core algorithm for server-side query execution is also simple: the query iterates field by field and performs a resolver for each field to handle data manipulation. Here’s an example:

On the far left is a GraphQL query that queries the title and content of all articles by the author whose ID is’ ABC ‘. The middle diagram shows the data type for each query field, and the parsing process for each field can be seen on the far right: first query the author with id ‘ABC’, and then retrieve all articles from that author; Since the article is a list, finally we need to traverse the list to get the corresponding title and content of each article.

This field-by-field parsing process is straightforward, but if the server implements it this way, it will face performance problems. The example below, if the user to query the article list under each author’s information, because there are probably huge quantities of repetition, the author of the article list when processing to the same authors will repeat query the author information, even when the “query information” author this operation itself contains large quantum operations, consumption of server performance is very significant:

One solution to the problem of a query triggering a large number of identical data operations is to change the data operations to batch processing. Still using the above example, in the following figure, we changed the operation of querying author information to store it in a queue, and then launch the query in batches at the appropriate time. At this time, the number of queries is only a minimum subset of the queue, avoiding repeated operations. Facebook’s DataLoder is one such solution for batch processing and caching of data.

The basic implementation ideas of GraphQL server are discussed above. For node.js implementation, I wrote a simple Demo based on the API Schema in the previous example, so that readers can understand how to implement and use GraphQL server in detail.

Client-side implementation

The common GraphQL client libraries are:

  • Relay: Facebook’s official GraphQL client, which is greatly optimized for performance but only available on the Web
  • Apollo: An open source community project designed to build a powerful and flexible GraphQL client for all development platforms (Web, Android, iOS, React Native, etc.)

For details on how to use these two client libraries, please refer to the official documentation. To get started with Apollo, the full-stack React + GraphQL Tutorial provides a simple example of how to build your first GraphQL application.

The development tools

GraphQL has a large number of practical development tools, which are based on introspection query implementation. The so-called introspection query refers to the query of API Schema information from the client to the server. For example, we can query meta fields such as __schema to get the full type information:

Query {__schema {types {name // Get the root field name fields {name // Get the field name}}}}Copy the code

The ability to query Schema information makes GraphQL’s document browser, auto-completion, code generation and other development tools easy to implement. GraphiQL is essentially a GraphQL client with editing, auto-completion, and document browsing functions. GraphiQL is a GraphQL client with editing, auto-completion, and document browsing functions. GraphiQL is a GraphQL client with editing, auto-completion, and document browsing functions.

Our server Demo also introduced GraphQL PlayGround, a debugging tool based on GraphiQL, in middleware form. After running the Demo, you can access localhost: 3000 / playground try cited above, all the query ~

Problems with GraphQL

Of course, GraphQL is not perfect either. Currently, GraphQL has two main issues: security and server caching.

Security issues

GraphQL’s declarative data query provides a flexible and easily extensible interface; However, if we launch a query that contains too many data operations, then this query will bring huge pressure to the data server, increasing the risk of being DDOS.

In addition, the query statement launched each time essentially reflects the structure of the query document. If an attacker intercepts our request and pieces together the complete interface content, it is not conducive to the security of the interface.

In the face of query pressure, traffic limiting on the server and client can be used to alleviate the pressure. For details about traffic limiting measures, see this article.

For the problem of API structure public transport, some people put forward a persistent query scheme. Simply speaking, the client and the server respectively convert the agreed query content into the query ID, and then use the query ID to query. This not only solves the problem of query statement public transmission, and only ID transmission also incidentally reduces the amount of data transmission, improve the transmission speed.

Server caching capability

GraphQL gives clients the flexibility to request data, which makes it difficult for servers to maintain a query cache based on the same connection.

As mentioned earlier, Facebook has a DataLoader technology for batch processing and caching of queries, but the caching described in the documentation is only for a single request and is coarse-grained.

conclusion

GraphQL, as a new API standard, provides clients with simple, flexible and efficient data query through declarative data acquisition. Adapting to the rapid development of client technology and rapid iteration of requirements in the era of mobile Internet, it is a strong competitor of the current REST mode.

GraphQL is currently being used in production environments by many companies (Facebook, GitHub, Twitter, etc.), and has a huge future ahead of it.

However, GraphQL’s own security issues can not be ignored; In addition, the introduction of GraphQL is bound to cost learning, and the changes in API design ideas will also affect the corresponding development mode and development process. So the costs and benefits of introducing the new technology must be weighed to make it useful.

Ref

How to use GraphQL