Как разрешить подполя, чтобы они добавляли необязательные параметры в HTTP-запрос?

Примечание: это очень упрощенный пример, но проблема та же.

Я пытаюсь обернуть существующую HTTP-службу /blog-posts интерфейсом GraphQL. Служба возвращает некоторые дополнительные данные в своем ответе, только если я передаю параметр запроса extra-data=true. Так,

  • GET /blog-posts: получает идентификатор и титул
  • GET /blog-posts?extra-data=true: получает идентификатор, заголовок и поле extra-data

У меня есть схема Absinthe, подобная следующей:

query do
  field :blog_posts, non_null(list_of(non_null(:blog_post)))
  resolve &MyAppWeb.Resolvers.Blog.posts/3
end

object :blog_post do
  field :id, non_null(:id)
  field :title, non_null(:string)
  field :extra_data, :string,
    resolve: &MyAppWeb.Resolvers.Blog.post_extra_data/3
end

Моя проблема в том, что я не знаю, как реализовать распознаватель extra_data, чтобы он не выполнял избыточный вызов /blog-posts?extra-data=true после того, как уже вызвал /blog-posts. Существует промежуточное ПО https://hexdocs.pm/absinthe/Absinthe.Middleware.Batch.html, предназначенное для решения аналогичной проблемы, N + 1 запросов, но я не вижу, как его применить в моем случае.

Какие-либо предложения?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 074
1

Ответы 1

Одно необязательное поле

Если это всего лишь одно дополнительное поле, вы можете передать необязательный аргумент в свой запрос:

query do
  field :blog_posts, list_of(:blog_post) do
    arg :extra_data, :boolean
    resolve &MyAppWeb.Resolvers.Blog.posts/2
  end
end

Несколько дополнительных полей

Но, если есть несколько необязательных аргументов, лучше использовать собственный input_object:

input_object :extra_input do
  field :extra_a, :boolean
  field :extra_b, :boolean
  field :extra_c, :boolean
end

query do
  field :blog_posts, list_of(:blog_post) do
    arg :extra_fields, :extra_input
    resolve &MyAppWeb.Resolvers.Blog.posts/2
  end
end

И в вашем преобразователе вы можете получить поля запроса и построить с ними URL-адрес HTTP-запроса:

def posts(%{extra_fields: extra}, _resolution) do
  # Here `extra` is a map of the optional fields requested. You can
  # filter selected fields, map them to their HTTP service name and
  # construct the HTTP url and query params before calling it in
  # one go
end

In both cases, remove the resolver you've specified directly on the :extra_data field in your :blog_post object.

Спасибо. Я могу вернуться к аргументу запроса, но я надеялся на более идиоматическое решение GraphQL, то есть сопоставление части графика с параметром HTTP-запроса extra-data.

Yawar 26.11.2018 06:07

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

Sheharyar 26.11.2018 07:14

Думаю, это обычный вариант использования. Я нашел два других сервера GraphQL, которые делают именно это (позвольте мне изучить выбранные вложенные поля в преобразователе более высокого уровня): lacinia.readthedocs.io/en/latest/resolve/… и sangria-graphql.org/learn/#projection. Думаю, я поговорю с ребятами из Absinthe о запросе функции.

Yawar 26.11.2018 19:33

Нашел! :-) Абсент уже имеет hexdocs.pm/absinthe/Absinthe.Resolution.html#project/2, который позволяет мне проверять вложенные выборки в текущем запросе. Я попробую это и напишу ответ.

Yawar 26.11.2018 19:56

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

Sheharyar 26.11.2018 20:01

Дайте мне знать, если вы не можете сделать это самостоятельно. Я отправлю еще один ответ с подходом Project / Resolution.

Sheharyar 26.11.2018 22:41

Спасибо! Раньше я не читал мелкий шрифт, project получает только подполя сразу под текущим полем в преобразователе. selects-field? Lacinia более мощный, он может ответить, использовалось ли поле в любом месте в запросе. Я сейчас копаюсь в структуре данных Resolution, чтобы попытаться сделать это вручную.

Yawar 27.11.2018 04:57

Другие вопросы по теме