Мы работаем над довольно сложной схемой GraphQL, где у нас есть несколько типов объектов, которые относятся к различным микросервисам, где каждый тип объекта имеет естественную конечную точку API, которую мы можем запросить. Поэтому было бы очень удобно, если бы можно было определить конкретные резольверы для определенных типов объектов непосредственно, делая что-то вроде этого:
const typeDefs = gql'
type Query {
getBook(bookId: ID!): BookPayload
}
type BookPayload {
book: Book
userErrors: UserError
}
type Book {
id: ID!
title: String
author: String
}
';
const resolvers = {
Query: {
getBook: (parent, args, context, info) => {
return {
book: { id: args.bookId }
}
},
Book: (parent) => { // this object type level resolver doesn't seem to work
return {
id: parent.id,
...fetchBookMetadata(parent.id)
};
}
};
Я понимаю, что это тривиальный пример и может показаться немного сконструированным, но он имеет больше смысла (по крайней мере для нас), когда схема начинает становиться очень сложной с сотнями перекрестных ссылок повсюду. Есть ли хороший способ решить это сейчас?
Да, вы должны иметь возможность сделать это или что-то очень похожее с помощью директив, проверьте это:
Я буквально отправлю цитату и пример из этой статьи здесь.
Предположим, вы определили тип объекта, который соответствует ресурсу REST, и вы хотите избежать реализации функций распознавателя для каждого поля
const typeDefs = '
directive @rest(url: String) on FIELD_DEFINITION
type Query {
people: [Person] @rest(url: "/api/v1/people")
}';
class RestDirective extends SchemaDirectiveVisitor {
public visitFieldDefinition(field) {
const { url } = this.args;
field.resolve = () => fetch(url);
}
}
Согласно спецификации, механизм выполнения GraphQL запускается над наборами наборов, которые разбиваются на отдельные поля. Каждое отдельное поле будет проверяться либо на значение, либо на существующий преобразователь.
Похоже, что если вы определяете директиву, такую как приведенная выше, вы не изменяете это основное поведение, но вы перехватываете и добавляете дополнительный настраиваемый шаг, который должен быть выполнен до дальнейшего разрешения.
Возможно, что-то подобное возможно с пользовательскими скалярами, но это не будет хорошо работать с дизайном схемы.