GraphQL - 将 ObjectType 传递给参数

Posted

技术标签:

【中文标题】GraphQL - 将 ObjectType 传递给参数【英文标题】:GraphQL - passing an ObjectType a parameter 【发布时间】:2017-01-02 07:50:28 【问题描述】:

我正在使用GraphQL,它运行良好,但是,我似乎无法弄清楚如何将参数传递到我的Event GraphQLObjectTypefields 部分。

我希望能够将currentUserId(通过令牌给我)传递给Event GraphQLObjectType,这样我就可以添加isAttending 属性。

我已经附上了我基本上想要做的 cmets 代码:

const Event = new GraphQLObjectType(
  name: 'Event',
  description: 'This represents an Event',
  fields: (currentUserId) =>  // currentUserId is the parameter I would like to pass in 
    return 
      id: 
        type: GraphQLInt,
        resolve (event) 
          return event.id;
        
      ,
      title: 
        type: GraphQLString,
        resolve (event) 
          return event.title;
        
      ,
      attendees: 
        type: new GraphQLList(User),
        resolve (event) 
          return event.getAttendees()
        
      ,
      // this is what I would like to do
      isAttending: 
        type: GraphQLBool,
        resolve (event) 
          return event.getAttendees(
            where: 
              id: currentUserId // that's the parameter I would like pass in
            
          ).then(attendee => 
            return (attendee.length > 0 ? true : false);
          );
        
      
      // end of what I'm trying to do //
    ;
  
);

const Query = new GraphQLObjectType(
  name: 'Query',
  description: 'Root query object',
  fields: () => 
    return 
      events: 
        type: new GraphQLList(Event),
        args: 
          id: 
            type: GraphQLInt
          
        ,
        resolve (root, args) 
          // here is the parameter I would like to pass to the event object
          let currentUserId = root.userId; 
          ////////

          return Db.models.event.findAll( where: args );
        
      ,
      ...

更新

我不能只做data.currentUserId = root.userId 的原因是因为当我返回collection of event objects 时它不可见,因为传递给我的Event GraphQLOBjectType 的只是event 对象。

当我执行data.currentUserId 并且data 内部有一个对象数组时的样子是这样的:

[objects, currentUserId: 1] 

与我们想要的相反:

[object, currentUserId: 1, anotherObject, currentUserId: 1] 

如果我想访问Event GraphQLObject 中的currentUserId,我唯一能想到的就是遍历每个对象并将currentUserId 添加到它上面,如下所示:

return events.map(event =>  
  event.currentUserId = currentUserId; 
  return event; 
);`

这是最好的解决方案吗?

【问题讨论】:

【参考方案1】:

恐怕你做不到。 fields 不接收任何参数,所以你也不会发送任何参数。

幸运的是,您可以通过更方便的方式实现这一点。

您的父类型 (Query) 在 resolve 函数中返回的所有内容都在子解析的 root 参数中可见。

const Query = new GraphQLObjectType(
    name: 'Query',
    description: 'Root query object',
    fields: () => (
            events: 
                type: new GraphQLList(Event),
                args: 
                    id: 
                        type: GraphQLInt
                    
                ,
                resolve (root, args) 

                    return Db.models.event.findAll( where: args )
                            .then(data => 
                                // pass the parameter here
                                data.currentUserId = root.userId;
                                return data;
                            );
                
            ,
            ...

那么您的 Event 对象将如下所示:

const Event = new GraphQLObjectType(
    name: 'Event',
    description: 'This represents an Event',
    fields: () => (

        ...

        isAttending: 
            type: GraphQLBool,
            resolve: (event) => 
                return event.getAttendees(
                    where: 
                        id: event.currentUserId // that's the parameter you've passed through parent resolve
                    
                ).then(attendee => 
                    return (attendee.length > 0 ? true : false);
                );
            
        
    )
);

【讨论】:

嘿,你能看看我对这个问题的更新吗?我尝试了您的解决方案,但不得不对其进行一些更改。请让我知道您的想法@LordDave 它可能看起来很难看,但我认为这是最好的也是唯一的解决方案。由于除了通过解析的根参数之外,没有其他方法可以将变量直接传递给子项,因此您必须使用这个新变量扩展集合中的所有对象。理想的解决方案是将其在 Sequelize 层上传递给结果,但不幸的是 Sequelize 做不到 我认为这是目前最好的解决方案。我实际上遇到了同样的问题,并编写了一个迭代器,它在 resolve 函数中通过 fieldASTs 运行,获取嵌套参数并允许根据参数查询字段。但是这个函数非常混乱,我很尴尬公开展示它:(实际上你已经可以为字段设置参数,但仅用于在获取后操作结果,即用 0 填充单个数字。 这似乎是 GraphQL 中的一个持续争论。 Facebook 自己显然通过让所有查询都从具有当前用户信息的 viewer 节点开始来处理它。

以上是关于GraphQL - 将 ObjectType 传递给参数的主要内容,如果未能解决你的问题,请参考以下文章

如何允许石墨烯GraphQl中的任何字段过滤

将 Typegoose 与 GraphQL 一起使用

如何发送包含扩展查询的 graphQL 查询?

nestjs 将接口转换为 graphql 类

使用 Nestjs 代码优先方法记录 Graphql 模式

Graphql自定义返回内容