如何在 GraphQL (Relay) 中查询和改变数组类型?

Posted

技术标签:

【中文标题】如何在 GraphQL (Relay) 中查询和改变数组类型?【英文标题】:How to query and mutate array type in GraphQL (Relay)? 【发布时间】:2020-06-25 15:25:22 【问题描述】:

我是 GraphQL/Relay 的新手,我在一个小项目上遇到了问题。我有一个包含“数组”类型字段的文档集合。请告诉我使用哪种类型的 GraphQL 来处理数组? 我尝试使用 GraphQLList,但遇到了一些错误,例如

“预期的 GraphQL 命名类型,但得到:[function GraphQLList]。”

和其他。 非常感谢您的帮助!

这是架构:

const mongoose = require('mongoose');
mongoose.set('useFindAndModify', false);
const Schema = mongoose.Schema;

const houseSchema = new Schema(
  name: 
    type: String,
    required: true
  ,
  events: 
    type: Array,
    default: []
  
);

var houseModel = mongoose.model("House", houseSchema);

module.exports = 
  getHouses: () => 
    return houseModel.find().limit(10).sort(_id:-1)
      .then(houses => 
        return houses.map(house => 
          return 
            ...house._doc,
            id: house.id
          ;
        );
      )
      .catch(err => 
        throw err;
      );
  ,
  getHouse: id => 
    return houseModel.findOne( _id: id );
  ,
  createHouse: house => 
    return houseModel(house).save();
  ,
  removeHouse: id => 
    return houseModel.findByIdAndRemove(id);
  ,
  updateHouse: (id, args) => 
    return houseModel.findByIdAndUpdate(
      id,
      
        name: args.name,
        events: args.events //-----------------
      ,
       new: true 
    );
  
;

“房子”的类型:

const 
  GraphQLList,
  GraphQLObjectType,
  GraphQLString
 = require('graphql');

const  globalIdField, connectionDefinitions  = require('graphql-relay');
const  nodeInterface  = require('../nodes');

const House = new GraphQLObjectType(
  name: "House",
  description: "lkjlkjlkjlkjlk",
  interfaces: [nodeInterface],
  fields: () => (
    id: globalIdField(),
    name: 
      type: GraphQLString,
      description: "Name of House"
    ,
    events: 
      type: GraphQLList,
      description: "Events list"
    
  )
);

const  connectionType: HouseConnection  = connectionDefinitions(
  nodeType: House
);

module.exports =  House, HouseConnection ;

变异:

const 
  GraphQLList,
  GraphQLObjectType,
  GraphQLNonNull,
  GraphQLString,
  GraphQLBoolean
 = require('graphql');

const  fromGlobalId, mutationWithClientMutationId  = require('graphql-relay');
const  House  = require('./types/house');

const houseModel = require('./models/house');

const CreateHouseMutation = mutationWithClientMutationId(
  name: "CreateHouse",
  inputFields: 
    name:  type: new GraphQLNonNull(GraphQLString) ,
    events:  type: new GraphQLNonNull(GraphQLList) 
  ,
  outputFields: 
    house: 
      type: House
    
  ,
  mutateAndGetPayload: args => 
    return new Promise((resolve, reject) => 
      houseModel.createHouse(
        name: args.name,
        events: args.events
      )
        .then(house => resolve( house ))
        .catch(reject);
    );
  
);

const UpdateHouseMutation = mutationWithClientMutationId(
  name: "UpdateHouse",
  inputFields: 
    id:  type: new GraphQLNonNull(GraphQLString) ,
    name:  type: new GraphQLNonNull(GraphQLString) ,
    events:  type: new GraphQLNonNull(GraphQLList) 
  ,
  outputFields: 
    updated:  type: GraphQLBoolean ,
    updatedId:  type: GraphQLString 
  ,
  mutateAndGetPayload: async (args) => 
    const  id: productId  = fromGlobalId(args.id);
    const result = await houseModel.updateHouse(productId, args);
    return  updatedId: args.id, updated: true ;
  
);

const RemoveHouseMutation = mutationWithClientMutationId(
  name: "RemoveHouse",
  inputFields: 
    id:  type: new GraphQLNonNull(GraphQLString) ,
  ,
  outputFields: 
    deleted:  type: GraphQLBoolean ,
    deletedId:  type: GraphQLString 
  ,
  mutateAndGetPayload: async ( id ,  viewer ) => 
    const  id: productId  = fromGlobalId(id);
    const result = await houseModel.removeHouse(productId);
    return  deletedId: id, deleted: true ;
  
);

const Mutation = new GraphQLObjectType(
  name: "Mutation",
  description: "kjhkjhkjhkjh",
  fields: 
    createHouse: CreateHouseMutation,
    removeHouse: RemoveHouseMutation,
    updateHouse: UpdateHouseMutation
  
);

module.exports = Mutation;

【问题讨论】:

【参考方案1】:

GraphQLList 是一个 wrapper 类型,就像 GraphQLNonNull 一样。它包装另一种类型。您可以像 GraphQLNonNull 一样使用它——通过调用构造函数并传入您要包装的类型。

new GraphQLList(GraphQLString)

两种包装器类型可以相互包装,因此您也可以这样做:

new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString)))

【讨论】:

以上是关于如何在 GraphQL (Relay) 中查询和改变数组类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GraphQL Relay 中捕获查询的响应

React GraphQL Relay - 如何进行简单查询?

如何使用 GraphQL 联合实现 Relay 节点查询

GraphQL + Relay:如何执行重新获取授权?

GraphQL / Relay - 是不是需要在主 QueryRenderer 中查询所有表?

使用 Relay 和 GraphQL 进行查询