#Implementing sql.Null* custom JSON marshaller/unmarshaller makes it unusable with libraries
6 messages · Page 1 of 1 (latest)
It would, if you embed them.
You could do smth like this (not tested):
type NullString struct {
sql.NullString
}
func (s *NullString) MarshalJSON() ([]byte, error) {
if !s.Valid {
return json.Marshal(nil)
}
return json.Marshal(s.String)
}
func (s *NullString) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte("null")) {
s.String = ""
s.Valid = false
return nil
}
return json.Unmarshal(b, &s.String)
}
func main() {
var s any = &NullString{}
_ = s.(sql.Scanner)
_ = s.(driver.Valuer)
_ = s.(json.Marshaler)
_ = s.(json.Unmarshaler)
}
No, defined types do not inherit methods:
https://go.dev/ref/spec#Type_definitions
You're absolutely right, I believe it's better to separate those. And if the service is complex enough your API objects are looking nothing like DB objects or logical entities, so you're probably already doing some sort of conversion between those. That being said, I've definitely used the own null structs approach for CRUD-ish services where the same type is used throughout db, api and logic, to keep things simple.