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
GETrequest and reading from firebase. - All fields are required when doing a
POSTrequest and serializing json body to struct. - Only the
Namefield is required when doing aPATCHrequest 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":""}
