見出し画像

Goでnull.Stringを扱う


背景

最近、GoでPATCH APIを実装する機会があり、その時、null.String を使ってリクエストを制御する必要があったので、この辺りを改めてキャッチアップしてみました。

Goでは、nullという概念はありません。
stringに空文字 "" を代入した場合、それはいわゆる「ゼロ値(zero value)」として扱われます。

しかし、Web APIを実装する以上、APIリクエストをしてくるクライアント側とのnull値の受け渡し、DBとのnull値の受け渡しは避けては通れません。

そこでGoでは、外部パッケージ gopkg.in/guregu/null.v1 を使うことで、Goでnullを許容できるstring型を扱うことが出来ます。

これは、

  • リクエストボディに、{"name" : null } のように、nullで来る可能性がある

  • DBに、name = NULL としてUPSERTしたい

  • DBから値を取得するとき、NULLの可能性がある

というようなケースの場合に有用です。

null.String型について

null.String型は以下のように定義されています。

type String struct {
	sql.NullString
}

null.Stringは、内部に sql.NullString が埋め込まれています。
sql.NullStringはどういう型かというと、

type NullString struct {
	String string
	Valid  bool // Valid is true if String is not NULL
}

上記のような型定義がされています。
実際の文字列としては String フィールドに値を持ち、 Validフィールドは、値があるかどうかをbooleanで表しています。
もし Valid = false であれば、その値はNULLである、という扱いです。

実装例

例えば、DBに空文字ではなく、NULLをUPSERTしたい場合は、以下のようにします。

type User struct {
	name null.String
}

func main() {
	user := User{
		name: null.NewString("", false), // Valid = falseとすることでNULLに設定
	}

	db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/database")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	_, err = db.Exec(`UPDATE user SET name = ? WHERE id = ?`, user.name, 1)
	if err != nil {
		log.Fatal(err)
	}
    // UPDATE user SET name = NULL WHERE id = 1
}
null.NewString("", false)

にて、Valid = false とすることで、意図的にNULLを設定し、その値をクエリビルダーに渡すことで、NULLとして値をセットします。

逆に、以下のようにセットした場合、 name = '' 空文字として値がセットされてしまいます。

user := User{
	name: null.StringFrom(""),
}

これは、null.StringFrom() の実装を確認してみると、

// StringFrom creates a new String that will never be blank.
func StringFrom(s string) String {
	return NewString(s, true)
}

この関数でnull.Stringを生成した場合、デフォルトで Valid = true となってしまうので、空文字としてUPSERTされます。

したがって、NULLでUPSERTしたい場合は、明示的にnull.NewString() で第2引数にfalseを渡す必要があります。


以上で、null.Stringの説明をしてきました。
とても使いやすいパッケージ・関数であると共に、正しくNULLを扱うために、仕様をきちんと理解しておく必要があると感じました。
今回、「どのようにNULLを定義しているのか」を知ることができたのでよかったです。
皆さんもぜひ、きちんとNULLの扱い方を把握した上で使ってみてください。


TuneCoreJapanではエンジニアを積極採用中です!
音楽xITの業界に興味がある方、ぜひご応募ください。


この記事が気に入ったらサポートをしてみませんか?