graphql,当存在“添加"时如何设计输入类型?和“更新"突变? [英] graphql, how to design input type when there are "add" and "update" mutation?
问题描述
这是我的要求:
-
"add"突变,
BookInput
输入类型的每个字段(或称为标量)都应具有附加的类型修饰符!".验证非空值.这意味着当我添加一本书时,该参数必须具有title
和author
字段,例如{title:"angular",author:"novaline"} 代码>
"add" mutation, every field(or called scalar) of
BookInput
input type should have additional type modifiers "!" to validate the non-null value. Which means when I add a book, the argument must havetitle
andauthor
field, like{title: "angular", author: "novaline"}
更新"突变,我想更新书的一部分字段,不想更新整本书(MongoDB文档,而且,我不希望前端通过graphql服务器整个大书突变论证以节省带宽).这意味着书中的参数可以是 {title:"angular"}
或 {title:"angular",作者:"novaline"}
.
"update" mutation, I want to update a part of fields of the book, don't want to update whole book(MongoDB document, And, I don't want front-end to pass graphql server a whole big book mutation argument for saving bandwidth). Which means the book argument can be {title: "angular"}
or {title: "angular", author: "novaline"}
.
这是我的类型定义:
const typeDefs = `
input BookInput {
title: String!
author: String!
}
type Book {
id: ID!
title: String!
author: String!
}
type Query {
books: [Book!]!
}
type Mutation{
add(book: BookInput!): Book
update(id: String!, book: BookInput!): Book
}
`;
就目前而言,"add"突变可以正常工作.但是,如果我通过了 {title:"angular"}
参数
For now, "add" mutation works fine. But "update" mutation cannot pass the non-null check if I pass {title: "angular"}
argument
这是一个无法通过非空检查的突变,缺少 BookInput
输入类型的作者"字段.
Here is a mutation which does not pass the non-null check, lack of "author" field for BookInput
input type.
mutation {
update(id: "1", book: {title: "angular"}) {
id
title
author
}
}
所以,graphql会给我一个错误:
So, graphql will give me an error:
{
"errors": [
{
"message": "Field BookInput.author of required type String! was not provided.",
"locations": [
{
"line": 2,
"column": 24
}
]
}
]
}
如何设计 BookInput
输入类型?不想定义 addBookInput
和 updateBookInput
.它是重复的.
How do I design the BookInput
input type? Don't want to define addBookInput
and updateBookInput
. It's duplicated.
推荐答案
一个非常常见的模式是为每个突变设置单独的输入类型.您可能还想为每个操作创建一个变异查询.也许是这样的:
A very common pattern is to have separate input types for each mutation. You may also want to create one mutation query per operation. Perhaps something like this:
const typeDefs = `
input AddBookInput {
title: String!
author: String!
}
input UpdateBookInput {
# NOTE: all fields are optional for the update input
title: String
author: String
}
type Book {
id: ID!
title: String!
author: String!
}
type Query {
books: [Book!]!
}
type Mutation{
addBook(input: AddBookInput!): Book
updateBook(id: String!, input: UpdateBookInput!): Book
}
`;
有些人还喜欢在更新输入中包含更新ID:
Some people also like to include the update ID as part of the update input:
const typeDefs = `
input AddBookInput {
title: String!
author: String!
}
input UpdateBookInput {
# NOTE: all fields, except the 'id' (the selector), are optional for the update input
id: String!
title: String
author: String
}
type Book {
id: ID!
title: String!
author: String!
}
type Query {
books: [Book!]!
}
type Mutation{
addBook(input: AddBookInput!): Book
updateBook(input: UpdateBookInput!): Book
}
`;
最后,您可能需要对返回类型使用有效载荷"类型-以增加灵活性(为您留出更大的空间来稍后更改返回类型,而不会破坏您的API):
Finally, you may want to use a 'payload' type for the return type - for added flexibility (gives you more wiggle room to change the return type later without breaking your API):
const typeDefs = `
input AddBookInput {
title: String!
author: String!
}
input UpdateBookInput {
# NOTE: all fields, except the 'id' (the selector), are optional for the update input
id: String!
title: String
author: String
}
type Book {
id: ID!
title: String!
author: String!
}
type AddBookPayload {
book: Book!
}
type UpdateBookPayload {
book: Book!
}
type Query {
books: [Book!]!
}
type Mutation{
addBook(input: AddBookInput!): AddBookPayload!
updateBook(input: UpdateBookInput!): UpdateBookPayload!
}
`;
希望这会有所帮助!
这篇关于graphql,当存在“添加"时如何设计输入类型?和“更新"突变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!