在没有解析器的情况下创建 GraphQL 字段

Creating a GraphQL field without a resolver

我将 Elixir 与 Phoenix 和 Absinthe 结合使用来设置 GraphQL 后端。

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

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

为此,我想我需要将模式中的 posts 字段委托给响应 publisheddraft 的对象。我是这样做的:

# 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

这没有用,而是 returns null 用于整个 posts 字段。但是,如果我更改架构中的 posts 字段以包含 "blank" 解析器,它会按预期工作:

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

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

此答案由 benwilson512 在 Elixir 论坛上提供。发帖分享答案


您在这里看到的行为是预料之中的,尽管通常您使用的虚拟解析器是:

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

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

不过,这些看起来更像是应该作为参数的东西 IE:

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