https://www.yuque.com/books/share/ec8980d3-bf8c-4277-a96d-957455adf289?# (password: xume) GraphQL tutorial
GraphQL introduction
- GraphQL is a data query language for API developed by Facebook and opened in 2015
- GraphQL is not only a query language for API, but also a runtime to meet your data query.
- GraphQL is an interface development standard that supports common server-side development languages. For example: Java, PHP, Python, node JS et al
- Official website: https://graphql.org/
- Chinese documents: https://graphql.cn/
- GitHub: https://github.com/graphql
- The future technology trend may replace RESTful, but it is not very good in recent years
- Because RESTful precipitated for many years
- A new project can all use GraphQL
- GraphQL is used in conjunction with RESTful
Reference link
- https://zhuanlan.zhihu.com/p/33876142
- dataloader
- https://github.com/graphql/graphiql
- 5 reasons for using / not using GraphQL
- https://github.com/mrdulin/blog/issues/88
Getting started with GraphQL
GraphQL related support
see: https://graphql.org/code/.
- back-end
- client
- tool
- service
GraphQL.js
GraphQL.js is a reference implementation of graphql.
- GitHub warehouse: https://github.com/graphql/graphql-js
- Use guide: https://graphql.org/graphql-js/
In order to process GraphQL queries, we need to define a schema of Query type. We also need an API root node to provide a function named resolver for each API endpoint. For return only Hello world! We can put this code in an API named server JS file:
const { graphql, buildSchema } = require('graphql') // 1. Build a schema using GraphQL schema syntax const schema = buildSchema(` type Query { hello: String } `) // 2. The root node provides a resolver function for each API entry endpoint const root = { hello: () => { return 'Hello world!' } } // 3. Run graphql query '{Hello}', and output the response graphql(schema, '{ hello }', root).then(response => { console.log(response) // Output result: {data: {Hello: 'hello world!'}} })
Express GraphQL
In practice, you may not execute GraphQL in the command-line tool, but want to run GraphQL queries from an API server. For example, node js Express.
1. Installation dependency
npm install express express-graphql graphql
2. Sample code
const { buildSchema } = require('graphql') const express = require('express') const { graphqlHTTP } = require('express-graphql') const cors = require('cors') const app = express() // Allow clients to cross domain requests app.use(cors()) // 1. Build a schema using GraphQL schema syntax const schema = buildSchema(` type Query { foo: String count: Int } `) // 2. Define resolver of scheme const rootValue = { foo () { return 'bar' }, count () { return 123 } } // 3. Mount GraphQL Middleware app.use('/graphql', graphqlHTTP({ schema, rootValue, graphiql: true // Open the browser GraphQL IDE debugging tool })) // 4. Start the Web service app.listen(4000, () => { console.log('GraphQL Server is running at http://localhost:4000/') }) // 3. Query // graphql(schema, '{ count, foo }', root).then(res => { // console.log(res) // })
Summary:
- The server specifies various forms of data that can be provided through the defined data types
- The field of type should have a corresponding resolver to provide corresponding resolution
- The client can selectively query the required field information according to the data type defined by the server
GraphQL client
With express GraphQL, you can send an HTTP POST request to the entry endpoint on the GraphQL server, where you can call the GraphQL server by taking the GraphQL query as the query field of the JSON payload.
An example of JavaScript request query is as follows:
axios({ method: 'POST', // The request method of GraphQL must be POST url: 'http://localhost:4000/graphql', data: { query: '{ foo, count }' } }).then(res => { console.log(res) })
GraphQL browser test tool
- Opening mode
- Basic use
- to write
- verification
- test
- Keyboard shortcuts
- Format query: Shift-Ctrl-P
- Merge query: Shift-Ctrl-M
- Execute query: Ctrl enter
- Autocomplete: Ctrl space
- consult your documentation
GraphQL patterns and types
Query type
- Strictly speaking, it is an object type
- Is the entry point for all queries
- Must be and cannot be repeated
Scalar type
The so-called scalar type is the basic type.
- Int: signed 32-bit integer.
- Float: signed double precision floating-point value.
- String: UTF ‐ 8 character sequence.
- Boolean: true or false.
- ID: the ID scalar type represents a unique identifier, which is usually used to retrieve the object or as a key in the cache. ID type is serialized in the same way as String; However, defining it as an ID means that human readability is not required.
object type
- In curly braces is the field information of the object
- Attribute names are custom
- The type after the property name is a scalar type built into GraphQL
- GraphQL uses # annotations
List type
# This means that the array itself can be empty, but it cannot have any null value members. myField: [String!] # Non nullable string array myField: [String]! # The array itself cannot be empty, and the data in it cannot be empty myField: [String!]!
Non empty type
- By default, each type is nullable, which means that all scalar types can return null
- An exclamation point can be used to mark a type, which cannot be empty, such as String! Represents a non empty String
- If it is a list type, use square brackets to wrap the corresponding types. For example, [Int] represents a list of integers.
Enumeration type
Also known as enum, enum type is a special scalar, which is limited to a special set of optional values. This allows you to:
- Verify that any parameter of this type is one of the optional values
- In communication with the type system, a field is always one of the values of a finite set of values.
enum Episode { NEWHOPE EMPIRE JEDI } #This means that no matter where we use episod in the schema, we can be sure that it returns one of NEWHOPE, EMPIRE and JEDI.
Mutation type
- Is the entry point for modification
Input type
- Parameter objects must be defined using Input
Server side example:
/** * schema Type: * - parameter * - modify * - Input type */ const { buildSchema } = require('graphql') const express = require('express') const { graphqlHTTP } = require('express-graphql') const cors = require('cors') const { v4: uuidv4 } = require('uuid') const app = express() app.use(cors()) const articles = [ { id: '1', title: 'article 1', body: 'article 1 body' }, { id: '2', title: 'article 2', body: 'article 2 body' }, { id: '3', title: 'article 3', body: 'article 3 body' } ] const schema = buildSchema(` type Article { id: ID! title: String! body: String! tagList: [String!] } # Entry point for query type Query { articles: [Article] article(id: ID!): Article } # Parameter objects must be defined using Input input CreateArticleInput { title: String! body: String! tagList: [String!] } input UpdateArticleInput { title: String! body: String! } type DeletionStatus { success: Boolean! } # Modify entry point type Mutation { createArticle(article: CreateArticleInput): Article updateArticle(id: ID!, article: UpdateArticleInput): Article deleteArticle(id: ID!): DeletionStatus } `) const rootValue = { articles () { return articles }, article ({ id }) { return articles.find(article => article.id === id) }, createArticle ({ article }) { article.id = uuidv4() articles.push(article) return article }, updateArticle ({ id, article: postArticle }) { const article = articles.find(article => article.id === id) article.title = postArticle.title article.body = postArticle.body return article }, deleteArticle ({ id }) { const index = articles.find(article => article.id === id) articles.splice(index, 1) return { success: true } } } app.use('/graphql', graphqlHTTP({ schema, rootValue, graphiql: true })) app.listen(4000, () => { console.log('GraphQL Server is running at http://localhost:4000/') })
Client example:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="./node_modules/axios/dist/axios.js"></script> <script> axios({ method: 'POST', // The request method of GraphQL must be POST url: 'http://localhost:4000/graphql', data: { query: ` mutation deleteArteicle($id: ID!) { deleteArticle(id: $id) { success } } `, variables: { id: 2 } } }).then(res => { console.log(res.data) }) // Update article axios({ method: 'POST', // The request method of GraphQL must be POST url: 'http://localhost:4000/graphql', data: { query: ` mutation updateArteicle($id: ID!, $article: UpdateArticleInput) { updateArticle(id: $id, article: $article) { id title body } } `, variables: { id: 2, article: { title: 'aaa', body: 'bbb' } } } }).then(res => { console.log(res.data) }) // Create article axios({ method: 'POST', // The request method of GraphQL must be POST url: 'http://localhost:4000/graphql', data: { query: ` mutation createArteicle($article: CreateArticleInput) { createArticle(article: $article) { id title body } } `, variables: { article: { title: 'aaa', body: 'bbb' } } } }).then(res => { console.log(res.data) }) axios({ method: 'POST', // The request method of GraphQL must be POST url: 'http://localhost:4000/graphql', data: { query: ` query getArticles($id: ID!) { article(id: $id) { id title } } `, variables: { id: 2 } } }).then(res => { console.log(res.data) }) // Get a single article const id = 1 axios({ method: 'POST', // The request method of GraphQL must be POST url: 'http://localhost:4000/graphql', data: { query: ` query getArticles { article(id: ${id}) { id title } } ` } }).then(res => { console.log(res.data) }) // Get article list axios({ method: 'POST', // The request method of GraphQL must be POST url: 'http://localhost:4000/graphql', data: { query: ` query getArticles { articles { title } } ` } }).then(res => { console.log(res.data) }) </script> </body> </html>