Получить имя операции запроса/мутации

Как я могу получить имя операции в контексте? В распознавателе я могу получить это с параметром info.

import { ApolloServer } from 'apollo-server'

const server = new ApolloServer({
  context: ({ req }) => {
    // Get query/mutation operation name like getAllUsers
  }
})

server.listen()

person Carlo Schneider    schedule 16.07.2019    source источник
comment
Вы могли бы передать фиктивный (но правильно сформированный) запрос — или, если на то пошло, реальный запрос, проверить объект req и довольно легко выяснить, какие ключи использовать для выделения информации, которая вам нужна?   -  person Thomas Hennes    schedule 16.07.2019
comment
@Jaxx Извините, req слишком большой. И на первый взгляд я не нашел ничего, что могло бы помочь.   -  person Carlo Schneider    schedule 16.07.2019
comment
Вы, вероятно, можете настроить таргетинг на req.body, так как я уверен, что именно там будет отображаться имя вашей операции, что уменьшит вывод. Кроме того, вы можете перенаправить вывод процесса вашего сервера в файл, что-то вроде npm run start > output.txt, запустить свой запрос, остановить (ctrl+c) сервер и найти в файле имя вашей операции.   -  person Thomas Hennes    schedule 16.07.2019


Ответы (2)


Используя метод, предложенный в моем комментарии, я смог получить имя операции.

Допустим, у вас есть следующий запрос:

query foo {
  baz {
    id
    name
  }
}

req.body имеет два важных ключа:

  1. req.body.query содержит весь запрос в строковом формате с сохранением пробелов и возврата каретки. Хотя вы можете получить имена операций из этой строки, это потребует некоторых манипуляций со строками; а именно, превращение строки в объект, а затем получение ключа (ов) корневого уровня (которых может быть несколько, если вы инициируете несколько операций в одном запросе). В приведенном выше примере этот ключ будет содержать следующую строку: 'query foo {\n baz {\n id\n name\n }\n}'.

  2. req.body.operationName содержит имя, которое вы дали своему запросу, ЕСЛИ вы его назвали. В приведенном выше примере этот ключ будет содержать 'foo' (а не 'baz', которое является названием фактической операции). Однако вы можете решить использовать эту возможность, тщательно назвав свои запросы в соответствии с операцией, которую они содержат (однако это не сработает, если вы инициируете несколько операций в одном запросе). Если вы не назовете свой запрос, это поле будет содержать null.

Изменить: см. раздел , как анализировать GraphQL. запросить строку в объект здесь, на SO, чтобы превратить строку, полученную в методе 1, в объект JS и получить фактическое имя операции.

Дополнительные соображения:

Например, метод 2 действительно подходит для целей отладки. Допустим, вы хотите регистрировать переменные для определенного запроса, вы можете назвать его и сделать следующее:

const server = new ApolloServer({
  context: ({ req }) => {
    if (req.body.operationName === 'debugMe') {
      console.log(req.body.variables)
    }
  }
})

Однако, поскольку метод 2 основан на том, что клиент присваивает имя запросу, его нельзя надежно использовать для целей бизнес-логики. Только метод 1 будет правильно извлекать имя операции независимо от того, как формируется запрос на стороне клиента.

person Thomas Hennes    schedule 16.07.2019

req, переданный в контекст, содержит req.body.query, но при тестировании с использованием PostMan для отправки запросов GraphQL я обнаружил, что параметр req моего сервера Apollo GraphQL НЕ содержит имя запроса (даже когда я называю его после объявления исходного запроса как Томас Хеннес правильно указал выше).

мой объект req ДЕЙСТВИТЕЛЬНО содержит req.body.variables.

Чтобы получить имя запроса, я извлекаю из тела первые 40 символов. Вы можете проанализировать это для первого { или ( или возврата каретки, но я просто хочу увидеть, что такое запрос/мутация, так что это работает для меня:

context: async ({req, connection}) => {
      ...
      ...
      let query = null;
      // mutation or query, not a subscription:
      const bodyQuery = req.body && req.body.query;
      if (bodyQuery) {
        query = req.body.query.substring(0,40);
      } else {
        query='No query passed in req body';
      }
      let variables = null;
      if (req.body.variables) {
        variables = req.body.variables;
      }
person NULL pointer    schedule 09.03.2021