在Go语言中Json管理是一个微不足道的问题,但是也会出现少数不可避免的问题:
- 如何为字段提供默认值?
- 如何使一个字段可选?
- 如何避免使用某些字段的默认值 (如 ︰ 用户 id)?
- 如何防止指针维护的问题
- 如何验证?
下面一些示例演示如将一个Struct解析成一个Json文档
我们来看一个在我们在日常开发中常用的一个Model,a User, a Scene, a Parcel,Models能够Marshaled Json,同样Json也能Unmarshaled为Models。在所有程序中,我们需要验证传入的Json。
当我们要把一个Json解析成Model的时候,我们利用结构标记来表示字段名称,比如我们可以用”omitempty”,来告诉程序我们是否忽略这个字段当它的值为空的时候。
1 2 3 4 |
type Model struct { UserId uint `json:"user_id"` Address string `json:"address,omitempty"` // if empty, don't encode it at all } |
默认字段
1 |
ProductCount uint // required, but zero is a safe default |
自定义默认字段
1 |
FavoriteColor string // a default is ok, but we don't want the empty string |
可选字段
1 |
Address *string // not required, but we still want to validate it if it's there |
取消引用的必填的字段
1 2 3 4 5 6 7 |
type Request struct { UserId *uint // this is a Required Non-Default Field, so it needs a pointer } type Model struct { UserId uint // but it's not optional, so we don't want the pointer in the model } |
简单验证
1 2 |
UserId *uint `validate:"nonzero"` Age Uint `validate:"min=18"` |
Pattern 1
Features: Default Fields, Easy Validation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// model type User struct { Name string `json:"name" validate:"nonzero"` Age uint `json:"age" validate:"min=1"` Address string `json:"address" validate:"nonzero"` } // unmarshalling var user User if err := json.NewDecoder(jsonByteSlice).Decode(&user); err != nil {...} // marshalling if jsonByteSlice, err := json.Marshal(object); err != nil {...} // validation if errs := validator.Validate(user); errs != nil {...} |
Pattern 2
Features: Default Fields, Optional Fields, Required Non Default Fields
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// model type User struct { Name *string `json:"name"` // required, but no defaults Age *uint `json:"age,omitempty"` // optional Address *string `json:"address,omitempty"` // optional FavoriteColor string `json:"favoriteColor"` // required, uses defaults } // unmarshalling var user User if err := json.NewDecoder(jsonByteSlice).Decode(&user); err != nil {...} // marshalling if jsonByteSlice, err := json.Marshal(object); err != nil {...} // validation func Validate(user User) { // default - validate value // optional - if non nil, validate value // required non default - validate not nil, then validate value } |
Pattern 3
Features: Default Fields, Optional Fields, Required Non Default Fields, Easy Validation
1 |
UserId *uint `validate:"nonzero,min=100"` |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// model type User struct { Name *string `json:"name" validate:"nonzero,min=1"` // required, but no defaults Age *uint `json:"age,omitempty" validate:"min=1"` // optional Address *string `json:"address,omitempty" validate:"min=1"` // optional FavoriteColor string `json:"favoriteColor"` // required, uses defaults } // unmarshalling var user User if err := json.NewDecoder(jsonByteSlice).Decode(&user); err != nil {..} // marshalling if jsonByteSlice, err := json.Marshal(object); err != nil {...} // validation if errs := validator.Validate(user); errs != nil {...} |
Pattern 4
Features: Default Fields, Required Non Default Fields, Easy Validation, Custom Default Fields,Dereferenced Required Fields
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// post request type UserPostRequest struct { Name *string `json:"name" validate:"nonzero"` // required, but no defaults Age *uint `json:"age"` // optional Address *string `json:"address"` // optional FavoriteInstrument string `json:"favoriteInstrument"` // required, uses defaults FavoriteColor *string `json:"favoriteColor"` // required, uses custom defaults } // model type User struct { Name string `json:"name" validate:"nonzero"` // required Age *uint `json:"age,omitempty" validate:"min=1"` // optional Address *string `json:"address,omitempty" validate:"min=1"` // optional FavoriteInstrument string `json:"favoriteInstrument"` // required FavoriteColor string `json:"favoriteColor" validate:"nonzero"` // required } // unmarshalling var postRequest UserPostRequest if err := json.NewDecoder(jsonByteSlice).Decode(&postRequest); err != nil {..} if errs := validator.Validate(postRequest); errs != nil {...} user.Name = *postRequest.Name user.Age = postRequest.Age user.Address = postRequest.Address user.FavoriteInstrument = postRequest.FavoriteInstrument user.FavoriteColor = "blue" if postRequest.FavoriteColor != nil { user.FavoriteColor = *postRequest.FavoriteColor } if errs := validator.Validate(user); errs != nil {...} // marshalling if jsonByteSlice, err := marshal(object); err != nil {...} // validation if errs := validator.Validate(user); errs != nil {...} |
参考文献:http://brandonokert.com/2016/04/18/Json-Management-Patterns-In-Go/
有疑问加站长微信联系(非本文作者)