GraphQL无法解析嵌套对象属性

时间:2016-08-30 22:20:36

标签: javascript json ajax graphql

我正在尝试使用列表中的一些嵌套属性对象返回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的类型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
        }
      },

编辑不是必需的,但这是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);
        });
    });
}

3 个答案:

答案 0 :(得分: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对象作为第一个值, 并从中返回基本值。

答案 1 :(得分:2)

我认为SubscriptionsList中的解析器必须返回subscription.subscription。我会考虑更改subscriptionsList的名称,因为它很混乱。

我看到它的方式,你应该有一个GraphQLList(订阅)并删除额外的嵌套级别。要么是这样,要么调用包含订阅的东西和客户的东西。

答案 2 :(得分:1)

根据您的帖子,// 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: { ... } }, {...} ] 显示以下内容:

subscriptions

现在,上述结果与Query中的SubscriptionsList字段相对应,SubscriptionsList// 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的值将是上面列表#1中的项目:

subscription

subscription类型中,您有一个字段subscription。它的resolve函数返回它得到的任何东西。因此,字段Subscription与列表#2保持一致。

在解析id字段(类型customer_id)时,它会在列表#2中显示的对象中查找subscriptionid属性。但该对象只有customer_id属性。因此,nullsubscription字段会收到// listing #3 { id: 'cbdemo_lloyd-sub2', customer_id: 'cbdemo_lloyd', plan_id: 'cbdemo_nuts', addons: [Object], due_invoices_count: 0, shipping_address: [Object] }, customer: { ... } } 个值。

因此,问题在于SubscriptionsList字段的解析功能。它的输入是清单#2中的对象,其输出应该是以下清单#3中的对象:

subscription : {
    type : Subscription,
    resolve : function (item) { // item is listing #2
        return  item.subscription; // item.subscription is listing #3
    }
}

要获取列表#3中的对象,请更改SubscriptionsList类型:

{{1}}

另一方面,GraphQL对象类型{{1}}在这里实际上是不必要的,并使整个事情变得复杂。没有它,整个设计将变得更加简单。