В GraphQL возможно ли иметь распознаватели на уровне типа объекта? - PullRequest
0 голосов
/ 13 сентября 2018

Мы работаем над довольно сложной схемой 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)
        };
    }
};

Я понимаю, что это тривиальный пример и может показаться немного сложным,но это имеет больше смысла (по крайней мере для нас), когда схема начинает становиться очень сложной с сотнями перекрестных ссылок повсюду.Есть хороший способ решить это прямо сейчас?

1 Ответ

0 голосов
/ 14 сентября 2018

Да, вы должны быть в состоянии сделать это или что-то очень похожее, используя директивы, проверьте это:

https://www.apollographql.com/docs/graphql-tools/schema-directives.html#Fetching-data-from-a-REST-API

Я буквально опубликую цитату и пример из этой статьи.здесь.

Предположим, вы определили тип объекта, соответствующий ресурсу 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 работает с наборами выбора, которые разбиты на отдельные поля.Каждое отдельное поле будет проверено на наличие значения или существующего преобразователя.

Кажется, что если вы определяете директиву, подобную приведенной выше, вы не изменяете это основное поведение, но перехватываете и добавляетедополнительный пользовательский шаг, который должен быть выполнен перед дальнейшим разрешением.

Возможно, что-то подобное возможно с пользовательскими скалярами, но это не будет хорошо работать с дизайном схемы.

...