如何使用嵌套模式进行GrahpQL变异

时间:2017-02-22 03:41:13

标签: javascript api graphql

我一直在编写一个使用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 } } }" }

我是否需要在我的变异模式中做一些特殊的事情才能允许这种类型的变异发生?

1 个答案:

答案 0 :(得分:0)

您不能使用Tag作为输入对象类型,您必须创建类似TagInput的类型

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

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

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" } ]
    }
}