GraphQL中有三種操作類型,分别是query、mutation、subscription:
- query: 擷取資料,對應CRUD裡的R;
- mutation: 操作資料,對應CRUD裡的CUD(建立,更新,删除);
- subscription: 消息訂閱,資料更改時進行消息推送.
之前已經學習了query, 這一篇重點學習mutation.
首先,修改models/article.go檔案,增加相應的CUD函數:
// Create a new article with the title and content provided
func CreateNewArticle(title, content string) (*Article, error) {
// Set the ID of a new article to one more than the number of articles
a := Article{ID: len(articleList) + 1, Title: title, Content: content}
// Add the article to the list of articles
articleList = append(articleList, a)
return &a, nil
}
// Update a article
func UpdateArticle(id int, title, content string) (*Article, error) {
a, err := GetArticleByID(id)
if err != nil {
return nil, err
}
if title != "" {
a.Title = title
}
if content != "" {
a.Content = content
}
return a, nil
}
// Delete a article
func DeleteArticle(id int) error {
for k, a := range articleList {
if a.ID == id {
articleList = append(articleList[:k], articleList[k+1:]...)
return nil
}
}
return errors.New("Article not found")
}
然後是修改schema/article.go,增加相應的mutation:
// 定義mutation,增删改操作
// add
var addArticle = graphql.Field{
Name: "新文章",
Description: "增加新文章",
Type: articleType,
Args: graphql.FieldConfigArgument{
"title": &graphql.ArgumentConfig{
Type: graphql.String,
},
"content": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
Resolve: func(p graphql.ResolveParams) (result interface{}, err error) {
title, _ := p.Args["title"].(string)
content, _ := p.Args["content"].(string)
result, err = models.CreateNewArticle(title, content)
if err != nil {
return nil, err
}
return result, nil
},
}
// update
var updateArticle = graphql.Field{
Name: "編輯文章",
Description: "編輯文章",
Type: articleType,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.Int,
},
"title": &graphql.ArgumentConfig{
Type: graphql.String,
},
"content": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
Resolve: func(p graphql.ResolveParams) (result interface{}, err error) {
id, _ := p.Args["id"].(int)
title, _ := p.Args["title"].(string)
content, _ := p.Args["content"].(string)
result, err = models.UpdateArticle(id, title, content)
if err != nil {
return nil, err
}
return result, nil
},
}
// delete
var deleteArticle = graphql.Field{
Name: "删除文章",
Description: "删除指定Id的文章",
Type: articleType,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.Int,
},
},
Resolve: func(p graphql.ResolveParams) (result interface{}, err error) {
id, _ := p.Args["id"].(int)
// 查找文章是否存在
result, err = models.GetArticleByID(id)
if err != nil {
return nil, err
}
if err = models.DeleteArticle(id); err != nil {
return nil, err
}
return result, nil
},
}
// 定義增删改方法
var mutationType = graphql.NewObject(graphql.ObjectConfig{
Name: "mutation",
Description: "增删改",
Fields: graphql.Fields{
"add": &addArticle,
"update": &updateArticle,
"delete": &deleteArticle,
},
})
// 定義Schema用于http handler處理
var Schema, _ = graphql.NewSchema(graphql.SchemaConfig{
Query: rootQuery,
Mutation: mutationType, // 這裡不能是nil了,對應前面的定義
})
測試結果話不多說,上圖:
新增文章:

編輯文章
删除文章
代碼在github上的連結
傳送門