Использование вложенных аргументов в операциях GraphQL - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть такая схема:

scalar Date

schema {
  query: Query
}

type Query {
  user(id: ID!): User
  messages(userId: ID!): [ChatMessage!]!
}

type User {
  id: ID!
  username: String!
  email: String!
}

type ChatMessage {
  id: ID!
  content: String!
  time: Date!
  user: User!
}

И я хочу сделать операцию, в которой вы можете получить все сообщения для пользователя, но поскольку User и ChatMessage находятся в отдельных таблицах базы данных Мне нужно выполнить два запроса (один, чтобы получить ChatMessages, а другой, чтобы получить User), поэтому я подумал, что должен смоделировать это так:

query findMessagesForUser($userId: ID!) {
  messages(userId: $userId) {
    id
    content
    user(id: $userId) {
      username
      email
    }
  }
}

Это возвращает ошибку разбора на схема:

GraphQLDocumentError: Неизвестный аргумент "id" в поле "ChatMessage.user".

Итак, как мне получить аргумент $userId, переданный в распознаватель для ChatMessage.user?

1 Ответ

0 голосов
/ 29 апреля 2020

В вашей схеме вы определили ввод идентификатора в вашем методе Query.user. В своем запросе вы пытаетесь указать идентификатор для свойства Message.user, однако вы не определили этот вход в вашей схеме.

Если вы хотите принять идентификатор в ChatMessage.user, вы ' Мне нужно определить его следующим образом:

type ChatMessage {
  id: ID!
  content: String!
  time: Date!
  user(id: ID!): User
}

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

Как указано @xadm, объект, который вы разрешили на уровне ChatMessage, будет передан в пользовательский преобразователь в качестве первого аргумента.

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

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

Я бы посчитал моделирование более похожим на это (фильтр ввода используется в качестве дополнительного надуманного примера):

type Query {
  user(id: ID!): User
  messages(filter: MessageFilter): [ChatMessage!]!
}

type MessageFilter {
  search: String
  paging: PagingFilter 
}

type PagingFilter {
  after: ID!
  pageSize: Int!
}

type User {
  id: ID!
  username: String!
  email: String!
  messages(filter: MessageFilter): [ChatMessage!]!
}

В вашей карте распознавателя вы может подключить ту же функцию для разрешения сообщений на уровне пользователя и на уровне запроса. Единственное отличие в том, что у вас не будет идентификатора пользователя на уровне запроса.

Если потребители хотят просматривать / искать сообщения от всех пользователей, они используют метод сообщений запроса верхнего уровня.

{
  messages({search: 'graphql'}) {
   id,
   content,
   time
  }
}

Если потребитель хочет просматривать / искать сообщения одного пользователя, go с помощью метода запросов пользователей верхнего уровня к сообщениям.

{
  user(id: 3) {
    messages({search: 'graphql'}) {
     id,
     content,
     time
    }
  }
}

Пример фильтра придуман, но может обеспечить базовую c подкачку для загрузки сообщений.

apollographql.com / docs / graphql-tools / resolvers

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...