假设我定义了一个结构 Foo
如下。
defmodule Foo do
@type t :: %__MODULE__{
bar: Bar.t()
}
defstruct bar: nil
end
我还定义了 Bar
:
defmodule Bar do
@type t :: %__MODULE__{
baz: String.t()
}
defstruct baz: nil
end
我还定义了 decode
对于两个 Foo
和 Bar
以使他们实施 Poison.Decoder
协议,并能很好地与 Poison.decode
尽管窝里斗。
我知道 as:
的选择 Poison.decode
可以用来拥有一个JSON文档,其形式为
{
"bar":
{
"baz": "this is baz!"
}
}
被解码成 %Foo{bar: %Bar{baz: "this is baz!"}}
但在我的例子中,我的地图上有一个字符串键,它指向的是 "我"。
然而,在我的例子中,我有一个地图的字符串键指向了 Foo
的,如。
{
"some_foo_key":
{
"bar":
{
baz: "this is some baz!"
}
},
"another_foo_key":
{
"bar":
{
baz: "another baz"
}
},
"yet_another_foo_key":
{
"bar":
{
baz: "and yet another baz"
}
}
}
我不认为这是消费HTTP APIs时的特殊情况 但我已经尝试了一些方法 但我仍然无法将前者解码成一个字符串键的映射,并指向 Foo
价值。我希望它是简单的,比如说
Poison.decode(data, as: %{String => %Foo{}}
但它只是返回JSON文档的映射表示,而没有将其解析成任何结构。
我很希望不用实现一个自定义的解码器,因为这需要保持它的实现与模型的变化同步。我有一种感觉,那就是 Poison.decode
已经能够处理这个问题,只是我漏掉了一些愚蠢的东西。另外,我发现Poison的文档有点欠缺。
你可以想象,这只是一个例子,实际的JSON响应包含了几个嵌套的对象,其中还包括我不感兴趣的字段。同样的响应被其他服务使用,所以我宁愿不用改变JSON表示方式(比如将keys作为一个额外的字段包含在 Foo
结构本身,并让 Poison 将数据解码为列表而不是地图,这很有效)。)
谢谢大家