【问题标题】:How to resolve sub-fields such that they add optional parameters to HTTP query?如何解析子字段以便将可选参数添加到 HTTP 查询?
【发布时间】:2019-04-27 15:10:40
【问题描述】:

注意:这是一个大大简化的例子,但问题是一样的。

我正在尝试使用 GraphQL 接口包装现有的 HTTP 服务 /blog-posts。仅当我传入查询参数extra-data=true 时,服务才会在其响应中返回一些额外数据。所以,

  • GET /blog-posts: 获取 ID 和标题
  • GET /blog-posts?extra-data=true:获取 ID、标题和 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 之后对/blog-posts?extra-data=true 进行冗余调用。有一个中间件 https://hexdocs.pm/absinthe/Absinthe.Middleware.Batch.html 旨在帮助解决类似的问题,N+1 查询,但我不知道如何在我的案例中应用它。

有什么建议吗?

【问题讨论】:

    标签: elixir graphql absinthe


    【解决方案1】:

    一个可选字段

    如果只是一个额外的字段,您可以在查询中传递optional argument

    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
    

    在您的解析器中,您可以获取请求字段并使用它们构建您的 HTTP 请求 URL:

    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
    

    在这两种情况下,删除您直接在 :blog_post 对象的 :extra_data 字段上指定的解析器。

    【讨论】:

    • 谢谢。我可以回退到查询参数,但我希望有一个更惯用的 GraphQL 解决方案,即将图形的一部分映射到 extra-data HTTP 查询参数。
    • 由于这不是一个常见的用例,您不会找到自动神奇™️ 进行转换的解决方案。在这里使用查询参数是正确的方法。
    • 我认为这是一个常见的用例。我发现另外两个 GraphQL 服务器可以做到这一点(让我在更高级别的解析器中检查选定的嵌套字段):lacinia.readthedocs.io/en/latest/resolve/…sangria-graphql.org/learn/#projections。我想我会和苦艾酒的人谈谈功能请求。
    • 找到了! :-) Absinthe 已经有了hexdocs.pm/absinthe/Absinthe.Resolution.html#project/2,它可以让我检查当前查询中的嵌套选择。我会试试这个并写一个答案。
    • Yes project 是一种替代方法,但用于检查是否在 graphql 查询中请求了某个字段。这也可以解决您的问题。
    猜你喜欢
    • 1970-01-01
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多