前回の続きで、下記の構造体の理解をします。前回はポインター面でしたが、今回は JSON にフォーカスして見ます。
// 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 の戻り値をあらわしたものです。それをシュミレートして見ましょう。
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 へ。これも簡単ですね。前回のポインタの回でお話しした通り、フィールドがポインタなので、値のセットが面倒です。(が、本番は、受け取るだけなのでこのような面倒なのは不要)さて実行。
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
というそれっぽいメソッドがありましたので使って見ます。
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 をマーシャル、つまり、構造体に入れたものです。第3引数は、プレフィックス、第4引数は、インデントです。さて、実行。
----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 に意味合いがすべての乗っていました。
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:"-,"`
よし、これで全部理解できました。