Go と Json の扱い

前回の続きで、下記の構造体の理解をします。前回はポインター面でしたが、今回は JSON にフォーカスして見ます。

```go
// DataFactory is the DataFactory Response
type DataFactory struct {
	autorest.Response      `json:"-"`
	ID                     *string             `json:"id,omitempty"`       // the identifying URL of the Data Factory.
	Name                   *string             `json:"name,omitempty"`     // the name of the data factory.
	Type                   *string             `json:"type,omitempty"`     // Resource Type
	Location               *string             `json:"location,omitempty"` // the supported Azure location of data factory.
	Tags                   *map[string]*string `json:"tags,omitempty"`     // A list of key-value pairs that describe the resource.
	*DataFactoryProperties `json:"properties,omitempty"`
}

// DataFactoryProperties is the Property of DataFactory
type DataFactoryProperties struct {
	DataFactoryID     *string `json:"datafactoryId,omitempty"`     // Auto-generated ID for this Data Factory.
	ProvisioningState *string `json:"provisioningState,omitempty"` // the current provisioning state of the Data Factory.
	Error             *string `json:"error,omitempty"`             // whether an error occurred during deployment.
	ErrorMessage      *string `json:"errorMessage,omitempty"`      // Message related to the error.
}
```

# JSON を扱う (Unmarshall)

この構造体は、REST-API の戻り値をあらわしたものです。それをシュミレートして見ましょう。

```go
func main() {
	body := `
{  
  "name": "test",  
  "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/adf/providers/Microsoft.DataFactory/datafactories/test",  
  "type": "Microsoft.DataFactory/datafactories",  
  "location": "westus",  
  "tags": {},  
  "properties": {  
    "dataFactoryId": "39d4e663-cfcb-4ee9-ad19-92cf87de9197",
    "provisioningState": "Succeeded",  
    "error": null,  
    "errorMessage": null  
  }  
} 
`

	var response DataFactory
	if err := json.Unmarshal([]byte(body), &response); err != nil {
		log.Fatal(err)
	}

	fmt.Println("DataFactoryId: ", *response.DataFactoryProperties.DataFactoryID)
	fmt.Println("Type: ", *response.Type)
	fmt.Println("Error: ", response.Error)

```

ヒアドキュメントで強引にレスポンスボディ値を作って、それをアンマーシャルして、正しく、構造体にセットされているかの確認です。しっかりできていますね。

```
$ go run cmd/client/main.go 
DataFactoryId:  39d4e663-cfcb-4ee9-ad19-92cf87de9197
Type:  Microsoft.DataFactory/datafactories
Error:  <nil>
```

ピックアップしたものですが、しっかりと帰ってきています。結構楽ですね。
さらにコードを書いていきます。

# Marshal

次は逆で、構造体から JSON へ。これも簡単ですね。前回のポインタの回でお話しした通り、フィールドがポインタなので、値のセットが面倒です。（が、本番は、受け取るだけなのでこのような面倒なのは不要）さて実行。

```go
func toAddress(str string) *string {
	return &str
}

　　　　　:

	adf := DataFactory{
		toAddress("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/adf/providers/Microsoft.DataFactory/datafactories/test"),
		toAddress("test"),
		toAddress("Microsoft.DataFactory/datafactories"),
		toAddress("westus"),
		&map[string]*string{"environemnt": toAddress("test")},
		&DataFactoryProperties{
			toAddress("39d4e663-cfcb-4ee9-ad19-92cf87de9197"),
			toAddress("Succeeded"),
			nil,
			nil,
		},
	}

	b, _ := json.Marshal(adf)
	fmt.Println("----json result---")
	fmt.Println(string(b))
```

実行結果

```
----json result---
{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/adf/providers/Microsoft.DataFactory/datafactories/test","name":"test","type":"Microsoft.DataFactory/datafactories","location":"westus","tags":{"environemnt":"test"},"properties":{"datafactoryId":"39d4e663-cfcb-4ee9-ad19-92cf87de9197","provisioningState":"Succeeded"}}
```

# Indent

ぐぬう。きっちゃない。もうちょっと読みやすくしたい。と思っていたら、`Indent` というそれっぽいメソッドがありましたので使って見ます。

```go
	b, _ := json.Marshal(adf)
	fmt.Println("----json result---")
	fmt.Println(string(b))
	fmt.Println("----Format---")
	var result bytes.Buffer
	json.Indent(&result, b, "", "  ")
	result.WriteTo(os.Stdout)
```

`Marshal` したものを、Indent メソッドに渡しています。ここでは、result のポインタを渡しています。b が、JSON をマーシャル、つまり、構造体に入れたものです。第３引数は、プレフィックス、第４引数は、インデントです。さて、実行。

```
----Format---
{
  "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/adf/providers/Microsoft.DataFactory/datafactories/test",
  "name": "test",
  "type": "Microsoft.DataFactory/datafactories",
  "location": "westus",
  "tags": {
    "environemnt": "test"
  },
  "properties": {
    "datafactoryId": "39d4e663-cfcb-4ee9-ad19-92cf87de9197",
    "provisioningState": "Succeeded"
  }
}
```

随分と見やすくなりました。残りは、最初の構造体についていた記号です。

# Json Marshal, Unmarshal のための記号


## func Marshal

[Marshall](https://golang.org/pkg/encoding/json/) に意味合いがすべての乗っていました。

```
type DataFactory struct {
	autorest.Response      `json:"-"`
	ID                     *string             `json:"id,omitempty"`       // the identifying URL of the Data Factory.
	Name                   *string             `json:"name,omitempty"`  
```

日本語で書いて見ます。（抜粋）

```
// JSON上の "myName"　を Field フィールドにマップ
Field int `json:"myName"`

// JSON上の　"myName" をField フィールドにマップ
// かつ該当するフィールドが、empty であれば、省略される
Field int `json:"myName,omitempty"`

// Field という名前のフィールドと、JSON 上のフィールドも同じ名前
// 該当フィールドが、empty であれば、省略される。
Field int `json:",omitempty"`

// Field という名前のフィールドは無視される
Field int `json:"-"`

// JSON のField に該当して、かつそのキーが "-," に該当する
Field int `json:"-,"`
```

よし、これで全部理解できました。

# リソース

* [Marshall](https://golang.org/pkg/encoding/json/)
* [Go言語でJSONを扱う](http://qiita.com/nayuneko/items/2ec20ba69804e8bf7ca3)