I am designing some REST API endpoints in Go. I use structs to define the object that handling in my API methods. These objects are sent as json and are stored in Firebase. Suppose I have the following simple struct:
type Person struct {
Name string `json:"name" firestore:"name"`
Gender string `json:"gender,omitempty" firestore:"gender"`
Nationality string `json:"nationality,omitempty" firestore:"nationality"`
}
And I have the following requirements:
- All fields are required when doing a
GET
request and reading from firebase. - All fields are required when doing a
POST
request and serializing json body to struct. - Only the
Name
field is required when doing aPATCH
request and serializing json body to struct.
What is the cleanest way to do serialization based on the same struct for all the methods? When doing the GET
request there is no problem, since all the fields are and need to be present in Firebase. However, when I am going to use the omitempty
tag for json serialization I cannot force the POST
request to contain all fields and the PATCH
request to contain only a subset of fields.
CodePudding user response:
I would probably write a validation function.
type Person struct {
Name string `json:"name" firestore:"name"`
Gender string `json:"gender,omitempty" firestore:"gender"`
Nationality string `json:"nationality,omitempty" firestore:"nationality"`
}
// ValidatePost validates the struct contains values for all mandatory fields for POST operations
func (p Person) ValidatePost()bool {
if p.Name =="" || p.Gender == "" || p.Nationality == ""{
return false
}
return true
}
// ValidatePatch validates the struct contains values for all mandatory fields for PATCH operations
func (p Person) ValidatePatch()bool {
if p.Name =="" {
return false
}
return true
}
CodePudding user response:
You could implement custom marshal interface or use a 3rd party lib like https://github.com/json-iterator/go
which support custom json tag
package main
import (
"fmt"
jsoniter "github.com/json-iterator/go"
)
type Person struct {
Name string `json1:"name" json2:"name"`
Gender string `json1:"gender,omitempty" json2:"gender"`
Nationality string `json1:"nationality,omitempty" json2:"nationality"`
}
func main() {
p := Person{Name: "bob"}
json1 := jsoniter.Config{TagKey: "json1"}.Froze()
json2 := jsoniter.Config{TagKey: "json2"}.Froze()
b1, _ := json1.Marshal(&p)
b2, _ := json2.Marshal(&p)
fmt.Println(string(b1))
fmt.Println(string(b2))
}
output:
{"name":"bob"}
{"name":"bob","gender":"","nationality":""}