GraphQL - 将 ObjectType 传递给参数
Posted
技术标签:
【中文标题】GraphQL - 将 ObjectType 传递给参数【英文标题】:GraphQL - passing an ObjectType a parameter 【发布时间】:2017-01-02 07:50:28 【问题描述】:我正在使用GraphQL
,它运行良好,但是,我似乎无法弄清楚如何将参数传递到我的Event GraphQLObjectType
的fields
部分。
我希望能够将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 传递给参数的主要内容,如果未能解决你的问题,请参考以下文章