【Go】JSONの入れ子を構造体に変換する
■ はじめに
APIから返ってくるJSON文字列をGolangの構造体に変換したいと思います。
■ JSONを構造体に変換する基本形
{ "book":{ "google_books_id": "Wx1dLwEACAAJ", "title": "リーダブルコード", "authors": ["Dustin Boswell","Trevor Foucher"], "description": "読んでわかるコードの重要性と方法について解説", "isbn_10": "4873115655", "isbn_13": "9784873115658", "page_count": 237, "published_year": 2012, "published_month": 6 } }
以下のように記述すればOKです。
type BookRequestParameter struct { GoogleBooksId string `json:"google_books_id"` Title string `json:"title"` Authors []string `json:"authors"` Description string `json:"description"` Isbn_10 string `json:"isbn_10"` Isbn_13 string `json:"isbn_13"` PageCount int `json:"page_count"` PublishedYear int `json:"published_year"` PublishedMonth int `json:"published_month"` }
■ JSONの入れ子を構造体に変換する
{ "book":{ "google_books_id": "Wx1dLwEACAAJ", "title": "リーダブルコード", "authors": ["Dustin Boswell","Trevor Foucher"], "description": "読んでわかるコードの重要性と方法について解説", "isbn_10": "4873115655", "isbn_13": "9784873115658", "page_count": 237, "published_year": 2012, "published_month": 6 }, "memo": { "body": "メモです。" } }
以下のどちらかの方法で構造体をフィールドに持つ構造体
を定義してあげれば良いです。
type RegisterUserBookRequestParameter struct { Book BookRequestParameter `json:"book"` Memo MemoRequestParameter `json:"memo"` } type BookRequestParameter struct { GoogleBooksId string `json:"google_books_id"` Title string `json:"title"` Description string `json:"description"` Isbn_10 string `json:"isbn_10"` Isbn_13 string `json:"isbn_13"` PageCount int `json:"page_count"` PublishedYear int `json:"published_year"` PublishedMonth int `json:"published_month"` PublishedDate int `json:"published_date"` } type MemoRequestParameter struct { Body string `json:"body"` }
type RegisterUserBookRequestParameterr struct { Book struct { GoogleBooksId string `json:"google_books_id"` Title string `json:"title"` Description string `json:"description"` Isbn_10 string `json:"isbn_10"` Isbn_13 string `json:"isbn_13"` PageCount int `json:"page_count"` PublishedYear int `json:"published_year"` PublishedMonth int `json:"published_month"` PublishedDate int `json:"published_date"` } `json:"book"` Memo struct { Body string `json:"body"` }`json:"user_book"` }
実際にAPIを叩いて受け取ったレスポンスを構造体に変換してみる
今回はGoogle Books APIを題材にしてみます。
Google Books APIはhttps://www.googleapis.com/books/v1/volumes?q=検索したい書籍名
の形式でリクエストを投げられます。
以下のコードはGoogle Books APIから受け取ったJSON形式のレスポンスをResponseBodyFromGoogleBooksApi構造体に変換しています。
// ResponseBodyFromGoogleBooksApi : GoogleBooksAPIを叩いた時のJSONレスポンスを格納する構造体 type ResponseBodyFromGoogleBooksApi struct { Items []Item `json:"items"` } type Item struct { ID string `json:"id"` VolumeInfo VolumeInfo `json:"volumeInfo"` } type VolumeInfo struct { Title string `json:"title"` Authors []string `json:"authors"` PublishedDate string `json:"publishedDate"` Description string `json:"description"` IndustryIdentifiers []IndustryIdentifier `json:"industryIdentifiers"` PageCount int `json:"pageCount"` } type IndustryIdentifier struct { Type string `json:"type"` Identifier string `json:"identifier"` } type GoogleBooksApiClientInterface interface { SendRequest(searchWord string) (ResponseBodyFromGoogleBooksApi, error) } func (client googleBooksApiClient) SendRequest(searchWord string) (model.ResponseBodyFromGoogleBooksApi, error) { searchURL := "https://www.googleapis.com/books/v1/volumes?q=" + searchWord // GoogleBooksAPIを叩く res, err := http.Get(searchURL) if err != nil { // エラーハンドリング } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { // エラーハンドリング } // JSONエンコードされたデータをparseして、構造体の変数responseBodyFromGoogleBooksApiに格納する var responseBodyFromGoogleBooksApi model.ResponseBodyFromGoogleBooksApi if err := json.Unmarshal(body, &responseBodyFromGoogleBooksApi); err != nil { // エラーハンドリング } return responseBodyFromGoogleBooksApi, nil }
■ JSONを構造体に変換する便利ツール
JSONを構造体の形式にマッピングするためには、json-to-goを使うと便利です。