This package aims to answer the question asked when implementing PATCH requests of RESTful API in Go:
Q: How to tell if a field is missing in the payload of a PATCH request?
Since we are using generics, Go 1.18+ is required.
Here we only talk about JSON payloads as it's the most frequently used format when developing a RESTful API.
Before implementaion, we need to define what is a missing field?
In this package, a field is defined as a missing field when:
- if the name/key of the field is not found in the JSON object
- or the name/key of the field is present but its value is
null
, null is interpreted as having no value
For example, in the following two JSON objects, field Name
is missing:
{ "Age": 18 }
{ "Name": null, "Age": 18 }
A Go snippet example:
type UserPatch struct {
Name string
Age int
Gender string
}
func PatchUser(rw http.ResponseWriter, r *http.Request) {
var payload UserPatch
json.NewDecoder(r.Body).Decode(&payload)
// Both the requests `{"Name":"","Age":18}` and `{"Age":18}` can
// cause `payload.Name == ""`.
// ** How can we distinguish the two? **
// "A field is missing" and "a field is empty" are semantically different.
if payload.Name == "" {
// do sth...
}
}
Using patch.Field
to define/wrap your fields in a struct.
import "github.com/ggicci/patch"
type UserPatch struct {
Name patch.Field[string]
Age patch.Field[int]
Gender patch.Field[string]
}
func PatchUser(rw http.ResponseWriter, r *http.Request) {
var payload UserPatch
json.NewDecoder(r.Body).Decode(&payload)
if !payload.Name.Valid {
// error: field "Name" is missing (not found or null)
}
}
Now we can tell a field is missing from a field is empty by consulting the sentinel Field.Valid
:
- when
Field.Valid == false
, then field is missing or is null - when
Field.Valid == true
, then field is provided and is not null