GraphQL 除了使用 Query 查詢資料外,若要異動資料,包含新增、修改、刪除,都要使用 Mutation。
Version
macOS Catalina 10.15
WebStorm 2019.2.3
Node 10.16.3
Apollo GraphQL 2.9.6
Apollo GraphQL
src/index.js
import { ApolloServer, gql } from 'apollo-server'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 }
]
let typeDefs = gql`
type Query {
books: [Book]
}
type Mutation {
addBook(book: BookInput!): Book
}
type Book {
title: String
price: Int
}
input BookInput {
title: String
price: Int
}
`
let books = () => data
let addBook = (_, { book }) => {
data = [...data, book]
return book;
}
let resolvers = {
Query: { books },
Mutation: { addBook }
}
let apolloServer = new ApolloServer({ typeDefs, resolvers })
apolloServer.listen()
.then(({ url }) => `GraphQL Server ready at ${ url }`)
.then(console.log)
第 9 行
type Query {
books: [Book]
}
在 Query
下宣告 books
query 回傳所有 Book
type 資料。
17 行
type Book {
title: String
price: Int
}
宣告 Book
type。
13 行
type Mutation {
addBook(book: BookInput!): Book
}
在 Mutation
下宣告 addBook
mutation 新增 book。
Mutation 雖然也能直接使用內建的 scalar type,如 String、Int,但因為 mutation 通常會新增大量資料,為避免 argument 太長,通常會搭配 Input
自訂 type。
22 行
input BookInput {
title: String
price: Int
}
使用 input
宣告 BookInput
input type,GraphQL 規定 input 命名須以 Input
為 postfix。
28 行
let books = () => data
books
query 直接回傳所有資料。
30 行
let addBook = (_, { book }) => {
data = [...data, book]
return book;
}
Apollo GraphQL 的 resolver 依序有 4 個 argument: parent
、args
、context
與 info
,讀取 argument 只會用到第二個 args
,而 parent
目前用不到可用 _
表示, context
與 info
目前可忽略。
從 args
直接 destructure book
,產生新的 id 直接新增至 id
property。
將 book
object 新增至 data 並回傳。
GraphQL Playground
query {
books {
title
price
}
}
使用 books
query,回傳其 title
與 price
兩個 property,共 2 筆資料。
mutation {
addBook(book: {
title: "Speaking JavaScript"
price: 300
}) {
title
price
}
}
使用 adeBook()
mutation,傳入 book
variable 為 argument。
回傳 book
object,重點是包含了剛新增的 id
property。
query {
books {
title
price
}
}
再次執行 query,會發現資料已經新增成功。
Conclusion
- Apollo GraphQL 的 query 與 mutation 寫法類似,唯 query 可直接使用 scalar type 與自訂 type;而 mutation 需使用自訂 input type
Reference
Eve Porcello, Use an Input Type to Create an Account with a GraphQL Mutation