在golang中将结构与其json逻辑分开?

时间:2016-01-15 07:12:49

标签: json go

是否有一种惯用的方法将结构与其json编组逻辑分开?

通常:

package models

type Foo struct {
  Name  `json:"full_name"`
}

但我想分开关注点。我不希望json包中的models指定逻辑包含结构,也可能将json逻辑放在另一个serializers包中。你会怎么做到惯用的去?可能类似于rails项目处理active_model_serializers代码

的方式

1 个答案:

答案 0 :(得分:2)

json标签是否属于编组逻辑或json 模型是有争议的。我想说指定json标签只是描述json模型,因此它可能更好地驻留在你的Go模型旁边。

编组/解组逻辑在encoding/json包本身中实现。如果需要自定义逻辑,可以通过实现json.Marshalerjson.Unmarshaler接口来指定/实现。这意味着为您的类型定义方法。在Go中,您只能为同一个包中的类型指定方法,因此如果您将模型与自定义解析逻辑分开,则解析包无法定义模型类型的方法。 Spec: Method declarations:

  

T表示的类型称为接收器基本类型;它不能是指针或接口类型,必须在方法的相同包中声明。

话虽如此,您需要在不同的类型上定义自定义解析逻辑,并且您需要进一步的逻辑来映射/复制到模型类型作为解析逻辑的一部分。通过将模型与解析逻辑分离,您将失去更多的收益。

更进一步,您编组的结构类型可能包含未导出的字段 - 如果解析逻辑位于同一个包中 - 可以正确初始化。通过分离模型和逻辑,逻辑将初始化未导出的字段时会遇到麻烦。一种方法是提供导出的方法或函数,但随后将其导出到其他所有人,而不仅仅是解析逻辑。

我会说Go方式和最简单的方法是将模型和解析逻辑放在同一个包中。它仍然为您提供“小”分离可能性:您可以将类型定义放在一个文件中(例如model.go),并且您可以放置​​自定义解析逻辑(实现json.Marshalerjson.Unmarshaler的方法)在另一个文件(例如parse.go)但当然在同一个包中,但最好在一个地方(在一个文件中)看到一个类型及其所有方法。