首页 文章

graphql,当有“添加”和“更新”变异时如何设计输入类型?

提问于
浏览
1

这是我的要求:

  • "add"变异, BookInput 输入类型的每个字段(或称为标量)都应该有一个额外的类型修饰符"!"来验证非空值 . 这意味着当我添加一本书时,参数必须有 titleauthor 字段,如 {title: "angular", author: "novaline"}

  • "update"变异,我想更新本书的一部分字段,为了节省带宽,想要前端传递graphql服务器整个大书变异参数 . 这意味着book参数可以是 {title: "angular"}{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"} 参数,"update"变异无法通过非null检查

这是一个不通过非空检查的突变, BookInput 输入类型缺少"author"字段 .

mutation {
  update(id: "1", book: {title: "angular"}) {
    id
    title
    author
  }
}

所以,graphql会给我一个错误:

{
  "errors": [
    {
      "message": "Field BookInput.author of required type String! was not provided.",
      "locations": [
        {
          "line": 2,
          "column": 24
        }
      ]
    }
  ]
}

如何设计 BookInput 输入类型?不想定义 addBookInputupdateBookInput . 这是重复的 .

1 回答

  • 0

    一种非常常见的模式是为每个突变分别提供输入类型 . 您可能还希望为每个操作创建一个突变查询 . 也许是这样的:

    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作为更新输入的一部分包含在内:

    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):

    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!
      }
    `;
    

    希望这可以帮助!

相关问题