追記: c.Bind とかする時に type error が起きたりするので Unmarshal も追加
あらすじ
MySQL で nullable なカラムレコードを入れるために struct の定義をこうしたらレコードには null が入らずに空文字が入ってしまいます。 Something.Code には Unique 制約をつけたいので空文字ではなく Null を挿入したい。
type Something struct { ID int `json:"id"` Code string `json:"code"` Name string `json:"name"` }
この問題自体は以下のように sql.NullString を使えば解決します。
type Something struct { ID int `json:"id"` Code sql.NullString `json:"code"` Name string `json:"name"` } s := Something{ID: 1, Code: sql.NullString{"", false}, Name: "something"}
なのですがこれを JSON にすると以下のようになるけどそうじゃないんだという場合にどうすればいいのかというお話です。
{ "id" : 1, "code" : { "String" : "", "Valid" : false }, "name" : "somethen" }
結果
型を定義しました。
type NullString struct { sql.NullString } func (s *NullString) MarshalJSON() ([]byte, error) { if s.Valid { return json.Marshal(s.String) } else { return json.Marshal(nil) } } func (s *NullString) UnmarshalJSON(data []byte) error { var str string json.Unmarshal(data, &str) s.String = str s.Valid = str != "" return nil } func NewNullString(s string) NullString { return NullString{sql.NullString{s, s != ""}} } type Something struct { ID int `json:"id"` Code NullString `json:"code"` Name string `json:"name"` } s := Something{ID: 1, Code: NewNullString(""), Name: "something"}
めでたし。
{ "id" : 1, "code" : null, "name" : "something" }