让Poison解码成 "map(String.t() => %Foo{}) "的正确`as:`参数是什么?

问题描述 投票:0回答:1

假设我定义了一个结构 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 对于两个 FooBar 以使他们实施 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 将数据解码为列表而不是地图,这很有效)。)

谢谢大家

json elixir elixir-poison
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.