If your application demands marshaling to JSON or another serialiazation format using Go, it can be tempting to design your structures to be cleanly serializable – often to the detriment of the implementation.
You might find yourself exporting variables you shouldn't be exporting, or creating elaborate ways to prevent mutability of attributes you care about.
If you find yourself doing this, stop, and consider the separation of concerns. JSON is a representation of your structure, and should not be directly tied to its underlying implementation, unless it's convenient. Although it's a bit more expensive, consider creating custom marshaling functions and generating one-off structs with the exact fields you need to decouple the implementation from representation.
In the following example, you don't want to export the Value
field from the Counter
struct, because it exposes your value to potentially unsafe operations (two incrementations at the same time, for example):
type Counter struct {