You know what? FaceBook, GitHub, Pinterest, Twitter, Sky, The New York Times, Shopify, Yelp, and many other big companies already use GraphQL’s interface specification. If you don’t study, you will lag behind.
Code GitHub link
Refer to the article
- A declarative GraphQL full stack instance
- If you do a good API Design
- Java Spring Boot implementation
- Medium GraphQL service design
The skills you will Get
- GraphQL concept
- Actual combat GraphQL – Query/Mutation/Subscription
- Rest vs GraphQL comparison analysis
- How to set up GraphQL backend service
- How to use React hooks, Providers to package GraphQL client
- How do I subscribe to data changes with GraphQL
Problems with the rise of the SPA framework
In the development of the front end will encounter such trouble?
1. API granularity in complex scenarios
- Reducing the number of requests requires merging requests
- Multi-terminal applications require different interfaces due to different Web, App, and applet views
- API interface granularity is difficult to determine
- Coarse-grained: Unnecessary traffic consumption on the mobile end
- Fine particle size: causes Function Explosion
1. API version division problem
- API versions need to evolve frequently
2. The interface styles for bidirectional communication are inconsistent
If you need to realize payment status, or multi-person collaboration, real-time synchronization of stock information to push data to the client, often need to use WebSocket communication or other communication methods. You’ll notice that if you ask the server to use Restful style, you won’t be able to keep the interface style consistent.
3. Components need to manage their own states
- The component needs to distribute asynchronous request state
- Parent-child component communication complicates the structure
- Subscribed data responses can clutter up the flow of data and make it less readable
GraphQL overview
English: graphql.org/
English: graphql. Cn /
Making GraphQL Explorer developer.github.com/v4/explorer…
concept
-
GraphQL is a query language created by Facebook for the API.
-
Specification of the way data is queried at the front and back ends.
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.
advantage
- The ability to define exactly the data you want (GraphQL has strong typing)
# query query {book(id:"1") {id, author,}} # result {"data": {
"book": {
"id": "1"."author": "Author1"}}}Copy the code
- GraphQL allows you to replace multiple REST requests with a single call to get the specified data
- Describes all possible types of systems
# query query {book(id:"1") {
id,
author,
},
book2 : book(id:"3"){id}} # result {"data": {
"book": {
"id": "1"."author": "Author1"
},
"book2": {
"id": "3"}}}Copy the code
- API evolution does not require versioning
Add fields and types to your GraphQL API without affecting existing queries. Old fields can be discarded and hidden from the tool. By using a single evolutionary version, the GraphQL API enables applications to always use new features and encourages cleaner, more maintainable server-side code.
GraphQL VS Restful
Extension reading REST, GraphQL, Webhooks, & gRPC
GraphQL | Restful | |
---|---|---|
Request multiple resources at once | ✔ ️ | ❌ |
API field customization | ✔ ️ | ❌ |
Define the return type precisely | ✔ ️ | ❌ |
No need to split versions | ✔ ️ | ❌ |
Type validation mechanism | ✔ ️ | ❌ |
Support two-way communication | ✔ ️ | ❌ |
Basic operation
Syntax description graphql.cn/learn/queri…
[Advanced Reading Complex Syntax — Fragments and Directives Function] juejin.cn/post/684490…
Query
Common query
query {
books {
title,
author
}
}
### Result
{
"data": {
"books": [
{
"title": "abc",
"author": "xxxx"
}
]
}
}
Copy the code
Queries with parameters and variables and aliases
# query($id:String) {book(id: $id) {id, author,}, book2: book(id: $id)"3"){id}} #"id":"1"} # result {"data": {
"book": {
"id": "1"."author": "Author1"
},
"book2": {
"id": "3"}}}Copy the code
Mutation
For non-idempotent operations such as data changes, Mutation is used for input description.
In REST, any request can end up causing some server-side side effects, but convention recommends against using GET requests to modify data. GraphQL is similar — technically, any query can be implemented to cause data to be written. However, a convention is established to specify that any operation that results in a write should be sent explicitly by mutation.
# mutation {createBook(title)"TTTT",author: "AAA") {
id
}
}
Copy the code
Subscription
If you want the backend to actively notify the front end of data changes, you can use the Subscription backend message Subscription feature.
subscription {
subsBooks
}
Copy the code
ApolloServer backend
ApolloServer is an open source GraphQL framework. ApolloServer can be used as a standalone server, and can also be used as a plug-in for Node frameworks such as Express and Koa.
HelloWorld
const { ApolloServer, gql } = require('apollo-server'); // Schema definition const typeDefs = GQL 'type Query {hello: String,}'; // The interpreter implements const resolvers = {Query: {hello: () => 'Hello world! '}}; Const server = new ApolloServer({typeDefs, resolvers}); Server.listen ().then(({url}) => {console.log(' 🚀 server ready at ${url} '); });Copy the code
Schema definition summary
The data type
GraphQL also has several basic types. In GraphQL, they are collectively called Scalar Type.
- Int (integer)
- Float (Float)
- String (String)
- Boolean (Boolean)
- ID (Unique identifier type)
- Custom types such as Date only need to implement the related serialization, deserialization, and verification functions
Object type
We can combine data types into objects as needed and these are collectively called object types.
type Book {
id:String
title: String
author: String
}
Copy the code
Other types of
For better code reuse GraphQl also provides more complex interface types that I won’t go over here.
- Enumeration types
- Union types
- Interface (s)
Query
// index.js
/ / add the Schema
const typeDefs = gql` type Query { books: [Book], book(id : String) : Book } type Book { id:String title: String author: String } `;
// Create data
const books = (
() = > Array(5).fill().map((v, i) = > ({
id: ' ' + i,
title: 'Title' + i,
author: 'Author' + i
}))
)()
/ / add the resolve
const resolvers = {
Query: {
books: () = > books,
book: (parent, { id }) = > {
return books.find(v= > v.id === id)
}
},
}
Copy the code
Mutation
const typeDefs = gql` type Mutation { createBook(title: String, author: String): Book! , clearBook : Boolean } `
resolvers.Mutation = {
createBook: (parent, args) = > {
constbook = { ... args,id: books.length + 1 + ' ' }
books.push(book)
return book
},
clearBook: () = > {
books.length = 0
return true}}Copy the code
Subscription
const { ApolloServer, gql, PubSub, withFilter } = require('apollo-server');
const typeDefs = gql` type Subscription { subsBooks : Boolean, } `;
const pubsub = new PubSub()
resolvers.Mutation = {
createBook: (parent, args) = > {
constbook = { ... args,id: books.length + 1 + ' ' }
books.push(book)
// Publish subscription messages
pubsub.publish('UPDATE_BOOK', {
subsBooks: true
})
return book
},
clearBook: () = > {
books.length = 0
// Publish subscription messages
pubsub.publish('UPDATE_BOOK', {
subsBooks: true
})
return true
}
}
resolvers.Subscription = {
subsBooks: {
// Filter messages that do not require subscriptions
subscribe: withFilter(
(parent, variables) = > pubsub.asyncIterator('UPDATE_BOOK'),
(payload, variables) = > true)}},Copy the code
GraphQL Client Communication (Axios)
Query
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.min.js"></script>
<script>
axios
.post("http://localhost:4000/graphql", {
query: `query { books { id title author } }`
})
.then(res= > {
console.log("res: ", res);
document.writeln(JSON.stringify(res.data))
});
</script>
Copy the code
Mutataion
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.min.js"></script>
<script>
axios
.post("http://localhost:4000/graphql", {
query: `mutation($title:String,$author:String) { createBook(title:$title,author:$author){ id } }`.variables: {
title: "TTTTT".author: "AAAAA"
}
})
.then(res= > {
console.log("res: ", res);
document.writeln(JSON.stringify(res.data))
});
</script>
Copy the code
GraphQL responsive data application
Response GraphQL structure
] (github.com/xitu/gold-m…).
React implements global status management
Refer to the article www.zcfy.cc/article/the…
Front-end data management Redux(command time) vs Apollo(declarative)
With Apollo we can try a completely different approach to front-end data management, declarative data management. In traditional projects, we often store data in a unified state management module such as Redux. Use ApolloClient to manage data through GraphQL data declaration. Each module can customize its own data according to its own needs.
Data connection Provider
const client = new ApolloClient({
uri: 'http://localhost:4000/graphql'}); ReactDOM.render(<React.StrictMode>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</React.StrictMode >,
document.getElementById('root')
);
Copy the code
Subscription needs to be consistent with the connection
// Subscription
// Create an http link:
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql'
});
// Create a WebSocket link:
const wsLink = new WebSocketLink({
uri: `ws://localhost:4000/graphql`.options: {
reconnect: true}});// using the ability to split links, you can send data to each link
// depending on what kind of operation is being sent
const link = split(
// split based on operation type
({ query }) = > {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink,
);
// Subscription
const cache = new InMemoryCache();
const client = new ApolloClient({
link,
cache
});
Copy the code
Query
import React, { useEffect } from 'react';
import { useQuery } from '@apollo/react-hooks';
import { gql } from 'apollo-boost';
const QUERY = gql` query { books { id, author, title } } `;
function Query() {
const { loading, error, data, refetch } = useQuery(QUERY)
useEffect(() = > {
refetch()
})
if (loading) return <p>Loading...</p>
if (error) return <p>Error :(</p>
console.log('book', data)
const list = data.books.map(v= > (
<div>{v.author}: {v.title}</div>
))
return list
}
export default Query;
Copy the code
Mutation
import React from 'react'; import { useMutation } from '@apollo/react-hooks'; import { gql } from 'apollo-boost'; const CREATE_BOOK = gql` mutation CreateBook($title:String! ,$author:String!) { createBook(title:$title,author:$author){ id, title, author } } `; const CLEAR_BOOK = gql` mutation { clearBook } `; function Mutation() { const [create, { data }] = useMutation(CREATE_BOOK); const [clear] = useMutation(CLEAR_BOOK) return ( <div> <form onSubmit={e => { e.preventDefault(); create({ variables: { "title": 'Title' + (Math.random() * 100).toFixed(), "author": 'Author'+ (Math.random() * 100).toFixed() } }); console.log('mutation:',data) }} > <button type="submit">Create</button> </form> <button onClick={ clear }>Clear</button> </div> ); } export default Mutation;Copy the code
Subscription
import React from 'react';
import { useSubscription } from '@apollo/react-hooks';
import { gql } from 'apollo-boost';
import Query from './Query'
const subs = gql` subscription { subsBooks } `;
function Subscription() {
useSubscription(subs)
return <Query/>
}
export default Subscription;
Copy the code
The appendix
Apollo Resources refer to this article juejin.cn/post/684490…
-
The service side
- [GraphQL – JS] Node (github.com/graphql/gra…). The initial implementation
- Graph-pack supports hot update zero-configuration GraphQL service environment
-
The client
- Relay Facebook’s GraphQL tool.
-
Prisma Bridges the gap between databases and GraphQL Resolvers, making it easier to implement production-level GraphQL servers. In addition to its powerful query engine and API, Prisma stands out in terms of the development experience. www.prisma.io/
-
Typeorm directly overuses the Models created in TypeGraphQL