Taka blog

プログラミングとか

[golang(Go言語)]json入門

APIサーバーでは、jsonを用いてデータのやり取りをすることが多いと思います。今回はjsonの基本的な使い方について、ご紹介します。

構造体とjson

リクエストとして受け取ったjsonを取り扱うために、golangではjsonを構造体に変換します。

ここでは、json変換の為の構造体定義を紹介します。main.goは下のコードのまま変えず、構造体の記述の違いによって出力される値(構造体を変換したjson)がどう変化するか、見ていきます。

package main

import (
	"encoding/json"
	"fmt"
	"json/domain/model"
)

func main() {
	u := model.User{
		Name: "james",
	}

	s, _ := json.Marshal(&u)

	fmt.Print(string(s))
}

基本

package model

type User struct {
	Name string
	Age  int
}

まず構造体は、このままでもjsonに変換することは可能です。この構造体をjsonに変換した場合、json内でのフィールド名は構造体のフィールド名と同じになります。

$ go run main.go
{"Name":"james","Age":0}

jsonタグでフィールド名を指定する

type User struct {
	Name string `json:"name"`
	Age  int    `json:""`
}

jsonタグを用いて、自由にjsonフィールド名を指定できます。タグを付けつつフィールド名を指定しないという無意味なことも可能で、フィールド名はそのままです。

$ go run main.go
{"name":"james","Age":0}

omitemptyか-でフィールドを除外する

type User struct {
	Name string `json:"-"`
	Age  int    `json:"age,omitempty"`
}

jsonフィールド名を-にすると、フィールドの値がどうであろうと変換時に無視されます。

,omitemptyを付けると、フィールドの値がゼロ値の場合そのフィールドが構造体から除外されます。フィールド名を指定せず",omitempty"だけでも可です。

$ go run main.go
{}

Marhal 構造体→json

	u := model.User{
		Name: "james",
	}

	s, _ := json.Marshal(&u)

	fmt.Print(string(s))

構造体のポインタが引数、[]byteとerrorが戻り値です。なおMarshlには1つだけ注意事項があるので記載します。

	var u *model.User
	s, _ := json.Marshal(u)

このように記述してしまうと、コンパイルエラーにはなりませんが、panicが発生します。原因は、Marshlの引数にnilを渡してしまっているからです。ポインタ型をvarで宣言する際は気をつけてください。

Unmarshal json→構造体

	u := model.User{
		Name: "james",
	}

	s, _ := json.Marshal(&u)

	fmt.Println(string(s))

	n := model.User{}
	_ = json.Unmarshal(s, &n)

	fmt.Printf("%+v", n)

Unmarshalでも、構造体のポインタを引数にしています。

出力結果は、フィールドが何も指定されていないのでゼロ値になります。

$ go run main.go
{}
{Name: Age:0}