1. What is GraphQL?
In terms of official definition, GraphQL is a query language for the API. GraphQL only defines how the query language syntax, how specific statements are executed, and so on. Just like the relationship between EcmaScript and JavaScript, it is possible to discover that the features described in the GraphQL standard have not yet been implemented; or that the implementation of GraphQL extends what the GraphQL standard defines.
Most of them follow the GraphQL standard, but they may be slightly different, and all of this requires you to explore.
2. How to get started with GraphQL ?
- Have a look at the standard first: http://graphql.org/ (pure GraphQL, nothing to do with any JavaScript, Python)
- Look at the server-side implementation: find the implementation related to language or framework you use at http://graphql.org/code/
- Look at the client implementation: Relay or appollo-client, etc.
- Learn to use DataLoader to get list data.
3. What is the difference between GraphQL and RESTful?
First of all, let’s talk about a picture below. Both REST and GraphQL are external service interfaces of the system that hosted by the server, so that those two APIs can be co-exist, and even they share the same business logic such as Authorization…etc.
So what is the difference between using GraphQL and RESTful? It is mainly two points.
* Entry point
The main idea of RESTful is resources, and a RESTful interface only operates on a single resource; therefore, when you use RESTful, you design a large number of interfaces. GraphQL is a single entry, generally configured in [host]/graphql/, and all resources are retrieved or modified from the entry via the graphql statement (of course GraphQL also supports multiple entries, but obviously the number of multiple entries is much smaller than RESTful).
* Data relevance
The resources that RESTful operates on are relatively discrete; GraphQL’s data is more holistic.
For example, if you want to get a friend of A’s friend, what should you do with RESTful?
Suppose we have such an interface like this:
GET /user/:userId/friends/
And A has 20 good friends, then we need to send 20 + 1 = 21 REST requests in total.
Or we designed the following interfaces for this particular scenario:
GET /user/:userId/friendsAndHisFriends/
ok…… Although it looks awkward, it only takes one request!
So what about GraphQL?
First we need to define a Schema for User (GraphQL has a complete type system):
Type User {
Id: ID!
Name: String!
Friends: [User]
}
Suppose we only have one Node on the Graph root, called user:
Type Query {
User(id: ID!): User
}
Then the query we send from the client can be written like this:
Query ($userId: ID) {
User(id: $userId) {
Name
Friends {
Name
Friends {
Name
}
}
}
}
In the end, this request finally will be able to find out the friend’s friends in this god damn requirement!! You might have discovered the this question: Can this query be written in an infinite loop? yep, you can do it! It is described on the official website of GraphQL:
It’s Graphs All the Way Down *
It is like a tree that extends infinitely downward. So in my opinion, GraphQL should be called TreeQL. Of course in graph theory, Tree is Graph and it is not a problem. It should be noted that this will also lead to the topic of “N + 1 problem” - naive’s GraphQL server implementation will make this query extremely slow!
4. Can GraphQL modify data?
The answer is: Yes.
Looking at the above examples, you must be curious, graphQL seems to be a language that exists only for search queries, is there a way to modify data?
Just to make the GraphQL data platform more complete, the GraphQL standard includes an operator called mutation. Because I think this design is quite general, here is the offical link you can check out: http://graphql.org/learn/queries/#mutations
5. What are the advantages of GraphQL compared to RESTful?
Data is more relevant and structured
This has been described in the third question in this article.Easier to cache data in the front end
This is generally done for you like Relay and apollo-client. If you want to understand its caching principle, please move to GraphQL Caching.Version-less API
Compared to the version number added by RESTful to be compatible with new and old clients, in GraphQL, if you need the server to provide different behavior than before, just modify the definition of root Query and add the Node you want above. Just fine.More robust interface
There is no need to bury an unstable time bomb for your system because of the lack of communications to modify the interface. All front-end interfaces have strong types of Schema guarantees, and the full type definition is completely visible to the front end because of introspection. Once the query sent by the front end does not match the Schema, it can quickly detect that an error has occurred.Expectant subscription
How to accept the push information of the server in the browser is a common problem. From the initial polling to the later WebSocket. Today, GraphQL also plans to introduce a third operator, subscription, in addition to query, mutation, in order to directly accept server push data. At the end of 2015, GraphQL officially published a blog post: Subscriptions in GraphQL and Relay to introduce subscription in their iOS and Android apps. Unfortunately, the related code is still not open source. Currently, the solution that the open source community can find is only the graphql-subscriptions written by the Apollo community for Node.js.
6. What are the disadvantages of using GraphQL?
Speaking of the many advantages of GraphQL, is there any drawback? Of course, there it is.
6.1. N+1 problem
The biggest problem is that when you implement your GraphQL server interface, it is easy to write very inefficient code which is called “N+1 problem.”
What is the N+1 issue? First let’s take a simple example:
Def get:
Users = User.objects.all()
For user in users:
Print(user.score)
This is a simple python code that uses Django’s QuerySet to fetch data from the database. Suppose we have two tables in our database. The relationship between User and UserScore is as follows:
Since the user’s score is not saved in the User table, and because the QuerySet has lazy loading feature, in the for loop, every time you get the user.score you will end up querying your database for the score data every single time in the loop. Ideally it should be an one time query job and now it becomes a N+1 queries.
Relative to RESTful, it is easier to cause N+1 problems in GraphQL. Mainly due to the layer-by-layer parsing of GraphQL query, see how GraphQL executes queries on GraphqlExecution for more details.
6.2. How to solve the N + 1 problem in GraphQL?
The following solutions are only for relational databases. If you are using NoSQL in your project, there may be a big difference for your solution.
For a one-to-one relationship (such as the relationship between User and UserScore mentioned in the example above), when you fetch data from the database, join the required data into a table. Don’t wait for the ORM framework to lazily load the data you need.
For a many-to-one or many-to-many relationship, you’ll need a tool library called DataLoader. Among them, Facebook provides their implementation of DataLoader for the Node.js. The main function of DataLoader is batching & caching, which can merge multiple database query requests into one, and the loaded data can be directly obtained from the DataLoader’s cache space.
7. Is there any way to happily debug the GraphQL interface?
GraphiQL / DEMO
Using GraphiQL makes it easy to feel the joy of “code as a document.”
8. How is paging handled in GraphQL?
This is a question that may be of concern to GraphQL beginners, and a question that can be found in the official documentation.
Taking a friend as an example, borrowing the filtering methods commonly used in SQL queries, the paging interface can be designed as:
Query ($userId: ID) {
User(id: $userId) {
Name
Friends(first: 2, offset: 3) {
Name
}
}
}
The above example means taking the first 2 friends from the 4th friend of $userId.
Similarly, the paging interface can also be designed to
- Friends(first: 2, after: $friendId);
- Friends(first: 2, after: $friendCursor)
Regardless of how the paging interface is designed, it needs to be packaged and supported together. Among them, the Relay-style paging interface has basically completed the implementation in the GraphQL framework of the front and back.
8.1 Relay-style paging interface
Note: apollo-client is compatible with this paging interface
Query {
User {
Name
Friends(first: 2, after: $cursor) {
Edge {
Curtain
Node {
Id
Name
}
}
pageInfo {
hasNextPage
}
}
}
}
9. How does user verification work in GraphQL?
You can look back. 3. What is the difference between GraphQL and RESTful? The answer is in the picture: Authentication is a business logic layer, you shouldn’t let GraphQL handle too much work.
Further reading: GraphQL Authentication