[ golang ]Go言語入門~ WebAPI ~

この記事は約11分で読めます。

今回は、WebAPI を利用するプログラムを作ります。

Day1では、画像分析を通して、他人が作ったプログラムを利用して、簡単に難しいものが作れるというお話でした。

[ Golang ] Go言語入門~ 画像を解析しよう ~
今回はGo言語を用いて、画像に埋め込まれている情報を取得する方法をご紹介します。一から作ると難しいですが、パッケージを使うことで、簡単に実装することができます。手を動かしながら学びましょう

 

さて、今回Web APIを使ったプログラムですが、そもそもAPIって何だろう?

となりますよね。そこから説明していきます

APIとは

API = Application Programming Interface(アプリケーション・プログラミング・インターフェイス)の略語です。このAPIには色々意味が存在しますが、大まかにいうと、アプリやプログラムのつなぎ目のことを指します。

普通システムは一から全て作る必要がありますが、特定の機能をまとめて、取得できればシステム毎に同じ処理を書く必要が無くなります。これがAPIです。

今回はWeb APIですので、ネットワーク、Webを通して、処理を取得して、自分のシステムに必要なデータを取り込みます。

今回の制作物

今回の制作物としては、2つ段階があります。

  1. プログラムでサイトからデータを取得する
  2. 公開されているWebAPIを使って、ビットコインの価格を取得する

この2つです。

まず1つ目のサイトからデータを取得するというのは、普段ブラウザで見ているページをプログラムで取得します。ネットにアクセスする基本的な使い方なので、是非知ってほしいです。

2つ目が今回の本題です。1.を応用して、

BitFlyerが公式で提供しているWebAPIを使って、ビットコインのデータを取得します。

この記事のゴール

  • プログラムからWEB上にあるデータをとる方法を知る
  • APIを知った上で、活用してみる(後々、APIを提供する側の記事も作成予定)

プログラムでネットワークからデータを取得する

まず、Go言語でネットワークのデータを取得します。今回はGoogleのトップページを取得してみます。

使用パッケージは全て標準で実装されているものです。最初に全コードをのせました。順に説明していきます。

 

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

var baseURL = "https://www.google.com/"

func main() {
	resp, err := http.Get(baseURL)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	byteArray, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(byteArray))
}

パッケージ

  • “fmt”…ターミナルに表示したり取得したり、インプットやアウトプットをする機能があるパッケージです。
  • io/ioutil…これもI/O系統のユーティリティです。
  • net/http…ネットワークに対しての機能が集まっているパッケージです。

コード説明

 

resp, err := http.Get(baseUrl)
if err != nil {
	panic(err)
}

ここでは、baseURLで指定されたページをhttp.Getで取得しています。戻り値には、アクセスした結果が含まれているrespとエラーが帰ってきます。エラーがあれば、panicで強制終了します。次に大事なのが、以下です。

 

defer resp.Body.Close()

 

基本、http系統は処理が終わればClose()を呼び出す必要があります。今回は単純なので、つけなくても影響はないですが、大規模になるにつれ、メモリが無駄に消費されることになります。

 

byteArray, err := ioutil.ReadAll(resp.Body)
if err != nil {
	panic(err)
}
fmt.Println(string(byteArray))

ここで、アクセスして帰ってきたデータの中身をByteに変換し、最後にfmt.Printlnでターミナルに表示します。

実行結果

$go run main.go
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja">
<head><meta content="&#19990;&#30028;&#20013;&#12398;&#12354;&#12425;&#12422;&#12427;&#24773;&#22577;&#12434;&#26908;&#32034;&#12377;&#12427;&#12383;&#12417;&#12398;&#12484;&#12540;&#12523;&#12434;&#25552;&#20379;&#12375;&#12390;&#12356;&#12414;&#12377;&#12290;&#12373;&#12414;&#12374;&#12414;&#12394;&#26908;&#32034;&#27231;&#33021;&#12434;&#27963;&#29992;&#12375;&#12390;&#12289;&#12362;&#25506;&#12375;&#12398;&#24773;&#22577;&#12434;&#35211;&#12388;&#12369;&#12390;&#12367;&#12384;&#12373;&#12356;&#12290;" name="description">
<meta content="noodp" name="robots"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title><script nonce="8YIRUlUAQw3AtQzc8QAFIw==">(function(){window.google={kEI:'xBK_XN2KGouj8QXR5Ze4Cw',kEXPI:'0,1353747,2014,2423,546,152,527,730,224,1575,1258,1894,57,527,351,172,494,8,217,237,175,2332963,329524,1294,12383,4855,32692,15247,867,12163,5281,9043,2197,363,530,2790,5505,2442,260,1027,2715,13
...

これで、googleのトップページをプログラムで取得することができました。

 

WebAPIを用いて、ビットコインの価格を取得する

 

次は、公式で提供しているWebAPIを用いて、ビットコインの価格を取得します。

WebAPIにはBitFlyerを用いました。

 

API一覧はこちら

 

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

var baseUrl = "https://api.bitflyer.jp/v1/getticker?product_code="

func main() {
	resp, err := http.Get(baseUrl + "btc_jpy")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	byteArray, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(byteArray))
}

パッケージ

1つめと同じです。

BitFlyerで使うエンドポイントは

https://api.bitflyer.jp/v1/getticker?product_code=<name>

product_codeに取得したい通貨を記入します。今回はビットコインなので、”btc_jpy”です。

実行結果

 

{"product_code":"BTC_JPY","timestamp":"2019-04-23T13:40:29.967","tick_id":8190481,"best_bid":625777.0,"best_ask":625778.0,"best_bid_size":3.82018599,"best_ask_size":1.029,"total_bid_depth":1577.27329791,"total_ask_depth":1041.31532119,"ltp":625777.0,"volume":506242.64241293,"volume_by_product":6125.5396541}

コードはほとんど同じなのに、結果の見やすさが違いませんか?

これが、WebAPIのメリットです。先ほどgoogleのページでは、WebAPIではなく通常のwebブラウザでみるようなので、人間には読みにくいのです。

一方、WebAPIはデータを使いやすくするために、上記のように整っています。

ちなみに、この表示形式をJSON形式と言います。少し前まで、XML形式が多かったのですが、モダンなwebではJSONがほとんどです。

プラスα

WebAPIから取得したデータは見やすくなりましたが、データを扱うことはできないですよね。

次は改良して、取得したデータを扱えるようにします。

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

var baseUrl = "https://api.bitflyer.jp/v1/getticker?product_code="

type Response struct {
	ProductCode string  `json:"product_code"`
	LTP         float64 `json:"ltp"`
}

func main() {
	resp, err := http.Get(baseUrl +"btc_jpy")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	byteArray, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Printf("プロダクト名:%+v\n", mapRes.ProductCode)
	fmt.Printf("価格:%+v\n", mapRes.LTP)
}

少し増えましたね。では見ていきましょう。

パッケージ

  • encoding/json…JSON形式のデータを扱うパッケージ

詳細

 

type Response struct {
	ProductCode string  `json:"product_code"`
	LTP         float64 `json:"ltp"`
}

 

WebAPIから取得したデータをResponse構造体にマッピングします。

実行結果には、タイムスタンプや諸々あったのですが、今回欲しかったデータだけResponseストラクトで定義しました。

ここで覚えてほしいのは、型の後ろにjson:"<name>"をつけることで、jsonのデータの中で<name>をこのResponseにマッピングできます。

次に変更点です。

mapRes := new(Response)
if err := json.Unmarshal(byteArray, &mapRes); err != nil {
	panic(err)
}

ここで、mapResというストラクトにJSON形式のデータをマッピングしています。

Marshal()XXをJSONに変換(Encode)
UnMarshal()JSONをXXに変換(Decode)

最後に

fmt.Printf("プロダクト名:%+v\n", mapRes.ProductCode)
fmt.Printf("価格:%+v\n", mapRes.LTP)

ここで、mapRes.ProductCodeでproduct_codeの値、mapRes.LTPでビットコインの価格を扱うことができます。

このようにWebAPIを活用するためには、

  1. GetやPOSTでWebAPIに対してアクセスする
  2. レスポンスデータを構造体(ストラクト)にマッピングする
  3. マッピングした構造体を使う

このような流れです。

まとめ

今回は

  • プログラムからWEB上にあるデータをとる方法を知る
  • APIを知った上で、活用してみる

について学びました。

APIはGoogleやIBM(Watson)など、色々な会社で提供しています。システムを開発する上で、WebAPIを用いることで、より早く、より精度を高く、システム開発できます。応用は無限大にあります。

 

[ConoHa]5分でGoのWebアプリをConoHaVPSで公開する方法

 

ぜひ使ってみてください

それでは。

タイトルとURLをコピーしました