【问题标题】:How to make a GrahpQL Mutation with nested schema如何使用嵌套模式进行 GraphQL Mutation
【发布时间】:2017-02-22 17:35:11
【问题描述】:

我一直在编写一个使用 GraphQL 的 API。我对它还是很陌生,并且遇到了一些关于突变的问题。我的 API 的简单形式有两种记录类型。有联系人记录和标签记录。一个联系人记录可以关联多个标签记录。

我为每种记录类型编写的架构如下:

const Tag = new graphQL.GraphQLObjectType({
name: 'Tag',
description: 'Categorizes records into meaningful groups',
fields: () => ({
  _id: {
    type: graphQL.GraphQLID
  },
  name: {
    type: graphQL.GraphQLString
  }
 })
});

const Contact = new graphQL.GraphQLObjectType({
name: 'Contact',
description: 'Contact record',
fields: () => ({
  _id: {
    type: graphQL.GraphQLID
  },
  name: {
    type: graphQL.GraphQLString
  },
  tags: {
    type: new graphQL.GraphQLList(Tag),
    resolve: function(src, args, context) {
      return TagModel.findByContactId(src._id)
        .then(tags => {
          return Promise.map(tags, (tag) => {
            return TagModel.findById(tag.tag_id);
          });
        });
      }
    }
   })
  });

我可以对标签等记录进行足够简单的突变,因为它们不包含自己的嵌套记录,但我不确定如何对联系人等记录进行突变,因为它也可以包含标签.我放置的变异代码如下所示:

const Mutation = new graphQL.GraphQLObjectType({
name: 'Mutation',
fields: {
  createContact: {
  type: Contact,
  description: "Create Contact",
  args: {
    name: {type: new graphQL.GraphQLNonNull(graphQL.GraphQLString)},
    tags: {type: new graphQL.GraphQLList(Tag)}
  },
  resolve: function(source, args) {
    return ContactModel.save(args.name);
  }
  } 
 }
});

我不确定如何在突变中完成解析器,以便能够同时保存联系人和标签记录。例如,如果我做了一个突变查询来保存一个带有新标签的新联系人记录,如下所示:

{"query": "mutation createNewContact { 
contact: createContact (name: "John Smith", tags { name: "family" } ) 
{_id, text, tags { name } } }" }

为了让这种类型的突变发生,我需要在我的突变模式中做些什么特别的事情吗?

【问题讨论】:

    标签: javascript api graphql


    【解决方案1】:

    你不能使用Tag作为输入对象类型,你必须创建一个像TagInput这样的类型

    const TagInput = new GraphQLInputObjectType({
        name: 'TagInput',
        fields: {
            _id: { type: GraphQLID },
            name: { type: GraphQLString } 
        }
    });
    

    建议始终创建您正常类型的Input 版本。您可以通过创建ContactInput 对Contact 执行相同的操作。然后你可以用非常相似的方式创建一个突变

    const Mutation = new GraphQLObjectType({
        name: 'Mutation',
        fields: {
            createContact: {
                type: Contact,
                args: {
                    contact: { type: new GraphQLNonNull(ContactInput) },
                    tags: { type: new GraphQLList(TagInput) }
                },
                resolve: (root, args, context) => {
                    console.log(args);
                    // this would console something like
                    // { contact: { name: 'contact name' },
                    //   tags: [ { name: 'tag#1' }, { name: 'tag#2' } ] }
                    // here create contact with tags
                }
        }
    });
    

    您将运行的query 看起来像这样

    {
        "operationName": "createContact",
        "query": "mutation createContact($contact: ContactInput!, $tags: [TagInput])
                  {
                      createContact(contact: $contact, tags: $tags) {
                          _id
                          text
                          tags {
                              name
                          }
                      }
                  }",
        "variables": {
            contact: { name: "contact name" },
            tags: [ { name: "tag#1" }, { name: "tag#2" } ]
        }
    }
    

    【讨论】:

    • 那行得通。谢谢!尽管在响应中取回标签数据,但我确实遇到了问题。即使我只是在解析器中返回 args 而什么都不做,所有属性都会返回,但标签只是一个空数组。像{联系人:_id:1,姓名:“约翰”,标签:[]}。我是否遗漏了返回标签数据所必需的内容?
    猜你喜欢
    • 2021-11-10
    • 2019-05-25
    • 2018-10-20
    • 2021-11-27
    • 2018-07-23
    • 2019-06-14
    • 2015-03-10
    • 2018-04-06
    • 2021-05-30
    相关资源
    最近更新 更多