【问题标题】:Better Jason encoder for schemas automatically自动为模式提供更好的 Jason 编码器
【发布时间】:2018-09-02 12:10:32
【问题描述】:

我收到了这个警告

警告:Jason.Encoder 协议已经整合,Any 的实现无效。如果您想在编译后或测试期间实现协议,请查看 Kernel.defprotocol/2 文档中的“合并”部分 lib/encoder.ex:1

警告:重新定义模块 Jason.Encoder.Any(从 /Users/dev/projects/haitracker.com/haitracker-be/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder 加载的当前版本.Any.beam) lib/encoder.ex:1

使用以下编码器

defimpl Jason.Encoder, for: Any do
  def encode(%{__struct__: _} = struct, _options) do
    skip_keys =
      case struct.__struct__ do
        Haitracker.User ->
          [
            :local_password_hash,
            :login_status_message
          ]

        # TODO: define skip keys for each model and pass to this function
        _whatever ->
          []
      end

    struct
    |> Map.from_struct()
    |> sanitize_map(skip_keys)
    |> Jason.encode!()
  end

  defp sanitize_map(map, skip_keys) do
    filter = fn {key, val} ->
      cond do
        key in [:__meta__, :__struct__] ->
          false

        is_map(val) ->
          Ecto.assoc_loaded?(val)

        key not in skip_keys ->
          true

        true ->
          false
      end
    end

    map
    |> Enum.filter(filter)
    |> Enum.into(%{})
  end
end

我想知道是否有更好的方法来编码我使用 Jason 的所有模式,只需一个编码器配置文件,以便在一个地方定义所有编码选项。

【问题讨论】:

  • @denis.peplin 实际上。不,我已经通过了所有README
  • 要求排除__meta____struct__字段,如果某些关联没有加载,我们也需要跳过这些字段。您可以将这些键称为全局跳过键和值。我想排除每个模式/模型的几个键。即本地skip_keys

标签: json encoding elixir schema phoenix-framework


【解决方案1】:

你显然不允许破坏默认的Jason 实现任何东西。你应该明确告诉Jason 你的结构是如何被序列化的。

摘自Jason README

如果你需要对一些没有实现协议的结构进行编码,如果你拥有该结构,你可以派生指定哪些字段应该编码为 JSON 的实现:

@derive {Jason.Encoder, only: [....]}
defstruct # ...

也就是说,您应该使用@derive 模块属性明确指定要过滤掉的字段。

【讨论】:

  • 问题是我想动态排除未加载的关联。否则你的解决方案是完美的。
  • 为此,您基本上有两个选择:实现NotLoaded 的协议或在编码之前过滤它们。
  • 过滤似乎是解决方案。因为如果我为 NotLoaded 实现协议,我必须返回一些前端开发人员不想要的东西,例如 NotLoaded 等或 nil。他们希望所有关联都具有对象值或在未加载时跳过
  • 好吧,我个人会为未加载的关联在消费者方面过滤掉使用特定的协商唯一值。决定如何处理不需要的值是前端的责任。只是在后端过滤掉它们会破坏一致性。
猜你喜欢
  • 1970-01-01
  • 2022-01-17
  • 2015-02-14
  • 1970-01-01
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多