Как создать вложенный резольвер в сервере apollo graphql
Учитывая следующую графическую схему сервера apollo
Я хотел разбить их на отдельные модули, поэтому мне не нужен запрос автора в корневой схеме запроса.. и хочу, чтобы он был разделен. Поэтому я добавил еще один слой с именем authorQueries перед добавлением его в Root Query
type Author {
id: Int,
firstName: String,
lastName: String
}
type authorQueries {
author(firstName: String, lastName: String): Author
}
type Query {
authorQueries: authorQueries
}
schema {
query: Query
}
Я попробовал следующее: вы можете видеть, что authorQueries был добавлен как другой слой до того, как указана функция автора.
Query: {
authorQueries :{
author (root, args) {
return {}
}
}
}
При запросе в Graphiql я добавил также дополнительный слой.
{
authorQueries {
author(firstName: "Stephen") {
id
}
}
}
Я получаю следующую ошибку.
"message": "Resolve function for \"Query.authorQueries\" returned undefined",
Ответы
Ответ 1
Чтобы создать "вложенный" резольвер, просто определите распознаватель для возвращаемого типа родительского поля. В этом случае ваше поле authorQueries
возвращает тип authorQueries
, поэтому вы можете поместить там свой резольвер:
{
Query: { authorQueries: () => ({}) },
authorQueries: {
author(root, args) {
return "Hello, world!";
}
}
}
Таким образом, в техническом смысле нет такой вещи, как вложенный резольвер - каждый тип объекта имеет плоский список полей, и эти поля имеют возвращаемые типы. Вложенность запроса GraphQL является тем, что делает результат вложенным.
Ответ 2
Я обнаружил, что возвращение функций в родительских полях, возвращающих тип, приводит к связыванию this
аргумента и нарушает интерфейс распознавателя, поскольку вложенный преобразователь не является родительским в качестве первого аргумента.
Для встроенных определений типов
import {
graphql,
} from 'graphql';
import {
makeExecutableSchema, IResolverObject
} from 'graphql-tools';
const types = '
type Query {
person: User
}
type User {
id: ID
name: String,
dog(showCollar: Boolean): Dog
}
type Dog {
name: String
}
';
const User: IResolverObject = {
dog(obj, args, ctx) {
console.log('Dog Arg 1', obj);
return {
name: 'doggy'
};
}
};
const resolvers = {
User,
Query: {
person(obj) {
console.log('Person Arg 1', obj);
return {
id: 'foo',
name: 'bar',
};
}
}
};
const schema = makeExecutableSchema({
typeDefs: [types],
resolvers
});
const query = '{
person {
name,
dog(showCollar: true) {
name
}
}
}';
graphql(schema, query).then(result => {
console.log(JSON.stringify(result, null, 2));
});
// Person Arg 1 undefined
// Dog Arg 1 { id: 'foo', name: 'bar' }
// {
// "data": {
// "person": {
// "name": "bar",
// "dog": {
// "name": "doggy"
// }
// }
// }
// }
Вы также можете использовать addResolveFunctionsToSchema
как показано ниже.
https://gist.github.com/blugavere/4060f4bf2f3d5b741c639977821a254f
Ответ 3
Я также сталкиваюсь с такой проблемой, но все еще не могу решить в моем конце. Любые входы будут полезны.
Я подал ошибку на graphql-tools на github, но пока не получил ответа.
https://github.com/apollographql/graphql-tools/issues/1026.
Привет команда,
Вложенные поля моей схемы не вызываются во время запроса.
схема
type XYZ {
title: String
}
type NestedLevel1 {
reference: XYZ
}
type ABCD {
title: String
reference: XYZ
nestedLevel1: NestedLevel1
}
type Query {
ABCDList(limit: Int, skip: Int): [ABCD]
}
//Resolvers
const Resolvers = {
Query: {
ABCDList: () => []
},
ABCD: {
reference: () => [] // this function is being called
nestedLevel1: {
reference: () => [] // this function is not being called
}
}
}
Вызывается функция резолвера "reference" верхнего уровня, но не решатель nestedLevel1.reference.