GraphQL 无法解析嵌套对象属性
Posted
技术标签:
【中文标题】GraphQL 无法解析嵌套对象属性【英文标题】:GraphQL unable to resolve nested object property 【发布时间】:2017-01-07 08:32:53 【问题描述】:我正在尝试返回一个带有列表中一些嵌套属性对象的 graphQL 查询。一切似乎都检查过了,但得到的是空值。
预期的数据结构响应(有关结构here 的更多详细信息):
//Return a GraphQLList type of all objects :
[
"subscription" :
,
"customer" :
,
,
]
查询: subscriptions subscription id customer_id
GraphQL 查询对象:
var Query = new graphQL.GraphQLObjectType(
name: 'Query',
description: 'Root of the Schema',
fields:
subscriptions:
type: new graphQL.GraphQLList(SubscriptionsList),
args :
customer_name: type: graphQL.GraphQLString ,
customer_id: type: graphQL.GraphQLString
,
resolve : function (source, args)
return getSubscriptions().then(function (res)
// Shows that data is returned
console.log('Data: ', res.list);
return res.list;
).catch(function (err)
return err;
);
);
期望返回类型 GraphQLList
of SubscriptionsList
:
var SubscriptionsList = new graphQL.GraphQLObjectType(
name : 'SubscriptionObj',
description : 'stuff',
fields : function ()
return
subscription :
type : Subscription,
resolve : function (subscription)
return subscription;
);
应该解析嵌套字段属性:
var Subscription = new graphQL.GraphQLObjectType(
name : 'Subscription',
description : 'stuff',
fields : function ()
return
id: type: graphQL.GraphQLString,
customer_id: type: graphQL.GraphQLString
);
Console.log(res.list) 输出(来自查询):我肯定得到了我期望的数据和结构:
[ subscription:
id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] ,
customer:
...
,
...
]
GraphQL 查询输出:
"data":
"subscriptions": [
"subscription":
"id": null,
"customer_id": null
,
"subscription":
"id": null,
"customer_id": null
,
EDIT 不是很必要,但这里是返回承诺的getSubscriptions()
API 调用:
function getSubscriptions()
return new Promise(function (resolve, reject)
chargebee.subscription.list(
limit : 5,
"plan_id[is_not]" : "basic",
"status[is]" : "active",
"sort_by[asc]" : "created_at"
).request(function(error,result)
if (error) return reject(error);
return resolve(result);
);
);
【问题讨论】:
【参考方案1】:根据您的帖子,res.list
显示以下内容:
// listing #1
[
subscription:
id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] ,
customer:
...
,
...
]
现在,上面的结果对应于Query
中的subscriptions
字段,这是SubscriptionsList
的列表。因此,SubscriptionsList
的值将是上述清单 #1 中的项目:
// listing #2
subscription:
id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] ,
customer:
...
在SubscriptionsList
类型中,您有一个字段subscription
。它的解析函数返回它得到的任何东西。因此,subscription
字段与清单 #2 保持一致。
在解析subscription
字段(类型Subscription
)时,它会在清单#2 中显示的对象中查找id
和customer_id
属性。但该对象只有 subscription
属性。因此,id
和 customer_id
字段接收 null
值。
因此,问题出在subscription
字段的解析函数中。它的输入是清单 #2 中的对象,其输出应该是以下清单 #3 中的对象:
// listing #3
id: 'cbdemo_lloyd-sub2',
customer_id: 'cbdemo_lloyd',
plan_id: 'cbdemo_nuts',
addons: [Object],
due_invoices_count: 0,
shipping_address: [Object] ,
customer:
...
要获取清单 #3 中的对象,请更改您的 SubscriptionsList
类型:
subscription :
type : Subscription,
resolve : function (item) // item is listing #2
return item.subscription; // item.subscription is listing #3
另一方面,GraphQL 对象类型SubscriptionsList
在这里实际上是不必要的,这使整个事情变得复杂。没有它,整个设计会变得简单很多。
【讨论】:
【参考方案2】:我认为您的 SubscriptionsList 中的解析器必须返回 subscription.subscription
。我会考虑更改subscriptionsList 的名称,因为它很混乱。
在我看来,您应该只拥有一个 GraphQLList(Subscription) 并删除额外的嵌套级别。要么这样,要么将包含订阅和客户的事物称为其他事物。
【讨论】:
【参考方案3】:看起来你有点糊涂了, 基本上,当你设置
new graphQL.GraphQLList(SubscriptionsList),
这已经是一个列表。 这意味着你真正的意思是
new graphQL.GraphQLList(Subscription),
接下来,您的订阅对象不包含任何解析逻辑, 所以我希望它是这样的:
var Subscription = new graphQL.GraphQLObjectType(
name : 'Subscription',
description : 'stuff',
fields : function ()
return
id:
type: graphQL.GraphQLString,
resolve: function(subscription)
return subscription.subscription.id;
,
customer_id:
type: graphQL.GraphQLString,
resolve: function(subscription)
return subscription.subscription.customer_id;
,
);
本质上发生的事情是,GraphQL 将使用 Subscription 对象解析提供的列表中的每个 javascript 对象。 每个解析器都会将 javascript 对象作为第一个值, 并从中返回基本值。
【讨论】:
小提示,如果你将console.log添加到Subscription的resolvers下,你应该能够看到列表中的每个对象,以确保你的方向是正确的 为什么我需要解析id
和customer_id
?我的getSubscriptions()
方法在返回响应时不是已经解决了吗?为什么 GraphQL 需要解析这些字段?
GraphQL 不知道如何处理对象。只有您为其定义的类型。基本上你是在声明一个新类型 Subscription
,然后你描述每个字段是如何解析的。这实际上是 GraphQL 的强大功能之一,因为 1 Object 不必与数据库层对象相同。更多信息可以找到here以上是关于GraphQL 无法解析嵌套对象属性的主要内容,如果未能解决你的问题,请参考以下文章