Может ли распознаватель GraphQL принудительно вызвать аргументы в parent? - PullRequest
1 голос
/ 25 марта 2019

Если у меня есть 2 типа: User и Note со следующей схемой:

query {
   getUser(userId: ID!): User
}

type User {
   userId: ID
   email: String
   notes: [Note]
}

type Note {
   noteId: ID
   text: String
}

Я пишу преобразователь для User#notes.Теперь, скажем, заметки нужно получать по адресу электронной почты, поэтому мне нужно, чтобы корневой объект, передаваемый в резолвер, содержал поле email, в любом случае я могу заставить GraphQL запросить поле email в объекте Userдаже если пользователь не запрашивал это?

С точки зрения кода, из того, что я вижу , я могу написать распознаватель.Как я могу гарантировать, что obj.email запрашивается всякий раз, когда пользователь запрашивает поле note?

User:  {
  notes(obj, args, context, info) {
    // How can I ensure obj.email is requested?
    return NoteRetriever.getNotesByEmail(obj.email);
  }
}

Редактировать

Меня интересует случай, когда родительresolver не разрешает поле email без явного запроса.Что если нам нужно сделать вызов API, чтобы получить электронное письмо для пользователя?Поэтому по умолчанию мы не запрашиваем это.Однако, когда запрашиваются заметки, имеет смысл запросить и электронное письмо.

Есть ли способ для распознавателя указать зависимость от родительских полей - чтобы обеспечить получение запроса?

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

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

Однако естьспособ сделать то, что вы просите при объединении схем.Это описано здесь https://www.apollographql.com/docs/graphql-tools/schema-stitching.

В основном необходимо иметь базовую схему, которая выглядит примерно так:

type Query {
    getUser(userId: ID!): User
}

type User {
   userId: ID
   email: String
}

С теми же решателями, что и у вас, и вторая схема, которая является чем-токак

type Note {
    noteId: ID
    text: String
}

extend type User {
    notes: [Note]
}

Наряду с чем-то вроде

import { mergeSchemas } from 'graphql-tools';

const finalSchema = mergeSchemas({
    schemas: [userSchema, noteSchema],
    resolvers: {
        User {
            notes: {
                fragment: '... on User { email }',
                resolve: notesResolver
            }
        }
    }
});
console.dir(await graphql(finalSchema, `query { ... }`));

Обратите внимание на свойство фрагмента, определяющее поле электронной почты.В приведенной выше ссылке описывается, как это приведет к разрешению данного поля на родителя при разрешении этого дочернего элемента.

0 голосов
/ 25 марта 2019

Значение «parent», передаваемое вашему распознавателю в качестве первого параметра, в точности соответствует тому, что было возвращено в преобразователе родительского поля (если только не было возвращено обещание, в этом случае оно будет соответствовать разрешенному обещанию).Поэтому, если у нас есть такой преобразователь:

Query: {
  getUser: () => {
    return {
      userId: 10,
      email: 'user@example.com',
      foobar: 42,
    }
  }
}

и запрос вроде:

query {
  getUser {
    id
    notes
  }
}

То, что передано нашему преобразователю notes, - это весь объект, который мы вернули внутри преобразователя дляgetUser.

User:  {
  notes(obj, args, context, info) {
    console.log(obj.userId) // 10
    console.log(obj.email)  // "user@example.com"
    console.log(obj.foobar) // 42
  }
}

Родительское значение будет одинаковым, независимо от запрошенных полей, если только логика распознавателя родительского поля на самом деле не возвращает другое значение в зависимости от запрошенных полей.Это означает, что вы также можете передать любое количество других произвольных записей (например, foobar выше) из родительского в каждое дочернее поле.

РЕДАКТИРОВАТЬ:

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

...