简体   繁体   English

对GraphQL中的嵌套类型进行深度查询返回NULL

[英]Deep query to nested types in GraphQL return NULL

Have a strange problem... 有一个奇怪的问题...

Query to nested types return null. 查询嵌套类型返回null。

But, if I return anything in parent type - resolve return right result 但是,如果我返回父类型的任何内容,请返回正确的结果

My code: 我的代码:

import { GraphQLList, GraphQLString, GraphQLID, GraphQLObjectType, GraphQLSchema } from 'graphql';
import AdminModel from '../models/Admin.model';

const AdminType = new GraphQLObjectType({
    name: 'AdminType',
    fields: {
        _id: { type: GraphQLID },
        login: { type: GraphQLString },
        password: { type: GraphQLString }
    }
});

const AdminRooteType = new GraphQLObjectType({
    name: 'AdminRooteType',
    fields: {
        getAdmins: {
            type: new GraphQLList(AdminType),
            resolve() {
                return AdminModel.find({})
            }
        }
    }
})

export default new GraphQLSchema({ 
    query: new GraphQLObjectType({
        name: 'RootQuery',
        fields: {
            admin: {
                type: AdminRooteType,
                resolve() {
                   // EMPTY RESOLVE - EMPTY RESULT
                }
            }
        }
    })
 });

Query: 查询:

{
  admin {
    getAdmins {
      login
    } 
  }
}

Result: 结果:

{
  "data": {
    "admin": null
  }
}

If I changed returned value in fields admin in RootQuery: 如果我在RootQuery的admin字段中更改了返回值:

import { GraphQLList, GraphQLString, GraphQLID, GraphQLObjectType, GraphQLSchema } from 'graphql';
import AdminModel from '../models/Admin.model';

const AdminType = new GraphQLObjectType({
    name: 'AdminType',
    fields: {
        _id: { type: GraphQLID },
        login: { type: GraphQLString },
        password: { type: GraphQLString }
    }
});

const AdminRooteType = new GraphQLObjectType({
    name: 'AdminRooteType',
    fields: {
        getAdmins: {
            type: new GraphQLList(AdminType),
            resolve() {
                return AdminModel.find({})
            }
        }
    }
})

export default new GraphQLSchema({ 
    query: new GraphQLObjectType({
        name: 'RootQuery',
        fields: {
            admin: {
                type: AdminRooteType,
                #resolve() {#
                    #// RETURN ANYTHING HERE:#
                  #  return 'foobar'#
                }
            }
        }
    })
 });

I've got expected result: 我有预期的结果:

{
  "data": {
    "admin": {
      "getAdmins": [
        {
          "login": "123"
        },
        {
          "login": "12asdf3"
        }
      ]
    }
  }
}

What is right solution for this issue? 什么是解决此问题的正确方法? (without using dummy values in return) (不使用虚拟值作为回报)

Thank's a lot! 非常感谢!

What you are seeing is the expected behavior. 您所看到的是预期的行为。 Imagine we have a User type with some fields: 假设我们有一个User类型,其中包含一些字段:

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: {
    id: { type: GraphQLID },
    name: { type: GraphQLString },
  }
})

And a way to fetch a single user: 还有一种获取单个用户的方法:

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    user: {
      type: AdminRooteType,
      resolve: () => getUser(),
    },
  },
})

If getUser returns an object representing a User , the resolvers for all the fields (ie id and name on the User type will be called. 如果getUser返回表示User的对象,则将调用所有字段的解析程序(即, User类型上的idname

When those fields (and whatever child fields they might have) resolve, you end up with a User object for the entire user field to return. 当这些字段(以及它们可能具有的任何子字段)解析后,您将得到一个User对象,整个user字段都将返回。 A response might look something like: 响应可能类似于:

"data": {
  "user": {
    "id": 1,
    "name": "Maria",
    "comments": [
      {
        "id": 1,
        // and so on...
      }
    ]
  }
}

Now, consider what happens when a user is not found and we return null instead. 现在,考虑当找不到用户而我们返回null时会发生什么。 Our response looks like this: 我们的回应如下:

"data": {
  "user": null
}

It doesn't make sense to call any of the resolvers for the User fields. 为“用户”字段调用任何解析程序都没有道理。 Would you expect the API to still return an id or name in this case? 在这种情况下,您是否希望API仍返回idname If it did, what values would those fields have? 如果这样做的话,这些字段将具有什么值? If we just returned a null id and name , how would the client distinguish that object from a User that existed but really did have id and name null values? 如果我们只是返回一个空的idname ,客户端将如何将该对象与一个已存在但确实具有idname null值的用户区分开?

The point is, if a field returns a GraphQLObjectType and it resolves to null, none of the resolvers on the GraphQLObjectType will be called. 关键是,如果字段返回GraphQLObjectType且解析为null,则不会调用GraphQLObjectType上的任何解析器。

By unnecessarily nesting your getAdmins field inside another GraphQLObjectType, you're forced to return some kind of object inside the resolver for admin . 通过不必要地将getAdmins字段嵌套在另一个GraphQLObjectType中,您被迫在解析器中返回admin某种对象。 So you will need to either live with that, or avoid creating an AdminRootType altogether and just put the getAdmins field on your Query type directly, as per convention: 因此,您将需要忍受这一点,或者避免完全创建AdminRootType而只需按照getAdminsgetAdmins字段直接放在查询类型上:

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    getAdmins: {
      type: new GraphQLList(AdminType),
      resolve: () => AdminModel.find({}),
    },
  },
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM