更好的杰森编码器自动用于模式



>我收到此警告

警告:Jason.Encoder 协议已经整合,Any 的实现不起作用。如果要在编译后或测试期间实现协议,请查看 Kernel.defprotocol/2 文档中的"整合"部分 lib/encoder.ex:1

warning:重新定义模块 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仅使用单个编码器配置文件,以便在一个地方定义所有编码选项。

您显然不允许破坏任何内容的默认Jason实现。您应该显式告知Jason如何序列化结构。

摘自杰森自述文件:

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

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

也就是说,您应该显式指定要使用@derive模块属性过滤掉哪些字段。

最新更新