You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Absinthe联合类型解析器向对象字段解析器传入空映射问题

解决Absinthe联合类型子解析器获取空映射的问题

我刚仔细看了你的代码,发现问题出在Absinthe处理联合类型的工作流程上——你在resolve_type里能拿到完整数据,但子对象解析器拿到空映射,是因为两者接收的数据来源不一样。

问题到底出在哪?

Absinthe处理联合类型的步骤是这样的:

  1. 先解析父字段(也就是:contact里的:info),拿到这个字段对应的数据列表;
  2. 对列表里的每一项数据,调用resolve_type判断它属于:foo还是:bar;
  3. 最后,子对象(:foo/:bar)的解析器会接收当前这一项的数据作为第一个参数。

你的代码里,:contact的:info字段没有自定义resolve函数,Absinthe会默认从父contact对象里读取:info字段的值。如果这个值是空的,子解析器自然就拿到%{}了。而你在resolve_type里能拿到数据,大概率是父字段其实有返回数据,但没有正确传递给子类型——这是因为你没给:info字段写正确的resolve逻辑。

怎么修复?

按照下面的步骤调整代码就行:

1. 给:contact的:info字段添加resolve函数

首先要确保:info字段返回的是包含每个子项完整数据的列表,比如模拟数据源的话可以这么写:

object :contact do
  field :info, list_of(:info) do
    resolve(fn _contact, _, _ ->
      # 这里替换成你实际获取数据的逻辑,比如从数据库查询
      info_items = [
        %{"info" => "foo", "phone" => "13800138000"},
        %{"info" => "bar", "id" => "bar_001"}
      ]
      {:ok, info_items}
    end)
  end
end

2. 调整子对象的解析逻辑

子对象的解析器第一个参数就是当前项的数据,直接从里面取字段就行:

object :foo do
  field :phone, non_null(:string), resolve: fn foo_data, _, _ ->
    IO.inspect(foo_data) # 现在会拿到%{"info" => "foo", "phone" => "13800138000"}
    {:ok, foo_data["phone"] || "hardcodedfornow"}
  end
end

object :bar do
  field :id, non_null(:string), resolve: fn bar_data, _, _ ->
    IO.inspect(bar_data) # 现在会拿到%{"info" => "bar", "id" => "bar_001"}
    {:ok, bar_data["id"] || "hardcodedfornow"}
  end
end

3. 完善resolve_type的默认分支

建议给resolve_type加个默认分支,处理未知类型的情况:

union :info do
  description("Union type representing foo or bar info")
  types([:foo, :bar])
  resolve_type(fn
    %{"info" => "foo"}, _ -> :foo
    %{"info" => "bar"}, _ -> :bar
    _, _ -> nil # 未知类型返回nil,Absinthe会抛出友好错误
  end)
end

核心逻辑再强调下

  • 父字段的resolve是负责拿数据的源头,必须返回正确的子项列表;
  • resolve_type只是做类型判断,不会修改或传递数据;
  • 子对象解析器接收的是单个子项的数据,不是父字段的整体数据。

这样调整后,你应该就能看到子解析器拿到正确的数据,而不是空映射了。

内容的提问来源于stack exchange,提问作者Raphael Rafatpanah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:21:07