Глубокий запрос к вложенным типам в GraphQL возвращает NULL - PullRequest
0 голосов
/ 11 февраля 2019

Возникла странная проблема ...

При запросе к вложенным типам возвращается значение null.

Но, если я возвращаю что-либо в родительском типе - разрешить возвращает правильный результат

Myкод:

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
                }
            }
        }
    })
 });

Запрос:

{
  admin {
    getAdmins {
      login
    } 
  }
}

Результат:

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

Если я изменил возвращаемое значение в полях admin в RootQuery:

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'#
                }
            }
        }
    })
 });

У меня ожидаемый результат:

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

Какое решение для этой проблемы?(без использования фиктивных значений в ответ)

Спасибо большое!

1 Ответ

0 голосов
/ 12 февраля 2019

То, что вы видите, - это ожидаемое поведение.Представьте, что у нас есть тип User с некоторыми полями:

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

И способ получения одного пользователя:

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

Если getUser возвращает объект, представляющий User, будут вызываться средства разрешения для всех полей (например, id и name для типа User.

Когда эти поля (и любые дочерние поля, которые они могут иметь) разрешаются, вы в конечном итогес объектом User для всего возвращаемого поля * 1015. Ответ может выглядеть примерно так:

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

Теперь рассмотрим, что происходит, когда пользователь не найден, а вместо этого мы возвращаем нуль. Наш ответ выглядиткак это:

"data": {
  "user": null
}

Не имеет смысла вызывать какие-либо средства распознавания для полей пользователя. Ожидаете ли вы, что API все равно будет возвращать id или name в этом случае? Еслиесли бы мы только что возвратили ноль id и name, как бы клиент отличил этот объект от пользователя, который существовал, но на самом деле имел id и name нулевые значения?

Дело в том, если полепревращает GraphQLObjectType и он разрешается в ноль, ни один из распознавателей в GraphQLObjectType не будет вызван.

Из-за ненужного вложения вашего поля getAdmins в другой GraphQLObjectType вы вынуждены возвращать какой-либо объект внутрираспознаватель для admin.Таким образом, вам нужно либо жить с этим, либо избегать создания AdminRootType в целом и просто поместить поле getAdmins в тип запроса напрямую, в соответствии с соглашением:

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    getAdmins: {
      type: new GraphQLList(AdminType),
      resolve: () => AdminModel.find({}),
    },
  },
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...