首页 > 解决方案 > 在没有解析器的情况下创建 GraphQL 字段

问题描述

我正在将 Elixir 与 Phoenix 和 Absinthe 一起使用来设置 GraphQL 后端。

理想情况下,我希望有一个如下所示的结构:

{
  posts {
    published {
      title
    }
    draft {
      title
    }
  }
}

为此,我认为我需要将posts架构中的字段委托给响应publishedand的对象draft。我这样做是这样的:

# In my Schema
field :posts, type: :posts_by_state

# In my Post type definitions
object :post do
  # ...
end

object :posts_by_state do
  field :published, list_of(:post) do
    resolve fn _, _, _ -> ... end
  end

  field :draft, list_of(:post) do
    resolve fn _, _, _ -> ... end
  end
end

这不起作用,而是返回null整个posts字段。但是,如果我更改posts架构中的字段以包含“空白”解析器,它会按预期工作:

field :posts, type: :posts_by_state do
  resolve fn _, _, _ -> {:ok, []} end
end

这是最佳实践还是有更好的方法来告诉字段完全委托给对象?更一般地说,有没有更好的方法来构建它?

标签: elixirgraphqlphoenix-frameworkabsinthe

解决方案


这个答案是由 Benwilson512 在 Elixir 论坛上提供的。在这里发帖分享答案


您在此处看到的行为是预期的,尽管您通常使用的虚拟解析器是:

field :posts, type: :posts_by_state do
  resolve fn _, _, _ -> {:ok, %{}} end
end

如果您不指定解析器,Absinthe 将使用默认解析器,该解析器执行Map.get(parent_value, field_name). 在您的情况下,如果根值是%{}(默认情况下),那么如果您没有指定帖子字段解析器,AbsintheMap.get(%{}, :posts)当然会返回nil。由于该字段返回nil,因此不执行任何子字段。

但实际上,这些看起来更像是应该作为参数 IE 的东西:

{
  published: posts(status: PUBLISHED) { title }
  draft: posts(status: DRAFT) { title }
}

推荐阅读