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

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

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

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

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

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 запросов, но я не вижу, как его применить в моем случае.

Есть предложения?

1 Ответ

0 голосов
/ 26 ноября 2018

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

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

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

В обоих случаях удалите определитель, указанный вами непосредственно в поле :extra_data в вашем :blog_post объект.

...