【问题标题】:GraphQL unable to resolve nested object propertyGraphQL 无法解析嵌套对象属性
【发布时间】: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);
        });
    });
}

【问题讨论】:

    标签: javascript json ajax graphql


    【解决方案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 中显示的对象中查找idcustomer_id 属性。但该对象只有 subscription 属性。因此,idcustomer_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下,你应该能够看到列表中的每个对象,以确保你的方向是正确的
        • 为什么我需要解析idcustomer_id?我的getSubscriptions() 方法在返回响应时不是已经解决了吗?为什么 GraphQL 需要解析这些字段?
        • GraphQL 不知道如何处理对象。只有您为其定义的类型。基本上你是在声明一个新类型 Subscription ,然后你描述每个字段是如何解析的。这实际上是 GraphQL 的强大功能之一,因为 1 Object 不必与数据库层对象相同。更多信息可以找到here
        猜你喜欢
        • 1970-01-01
        • 2019-12-21
        • 2018-08-27
        • 1970-01-01
        • 1970-01-01
        • 2021-02-15
        • 1970-01-01
        • 2018-09-02
        • 2018-12-08
        相关资源
        最近更新 更多