BODIK APIを使ったJavascriptプログラムを書いてみます。

課題1:BODIK APIを呼び出してみる

問題:BODIK APIを使って、AEDを検索してみる。

基本情報

  • JavascriptからWebAPIを呼び出す方法はいくつかありますが、ここでは「fetch」を使います。
  • BODIK APIの検索結果はJSON形式で取得できます。
  • 検索結果は辞書形式データの配列になっています。
  • Javascriptで配列の各要素を調べる場合、「for ... of ...」を使います。

swaggerで試す

最初に、WAPIのswagger(https://wapi.bodik.jp/docs)でAPIを試してみましょう。

AED(GET /aed)のエンドポイントを表示し、「try it out」のボタンを押して、下の方にある青い「Execute」ボタンを押してみます。

検索結果が表示されます。「Request URL」のところを確認します。

「Request URL」は「?」の前方がAPIのURL部分、後方がパラメータになります。

    URL部分       パラメータ部分
https://wapi.bodik.jp/aed?select_type=data&maxResults=10&distance=2000

URL部分

https://wapi.bodik.jp/aed

これを分解すると
 BODIK APIのURL:https://wapi.bodik.jp
 データセット名:aed

パラメータ部分:複数のパラメータが「&」で結合されています。

select_type=data&maxResults=10&distance=2000

これを分解すると
 select_type=data
 maxResults=10
 distance=2000

Javascriptで記述

では、Javascriptで「BODIK API」を呼び出してみましょう。

JavascriptからWebAPIを呼び出す方法はいくつかありますが、ここでは「fetch」を使います。
「javascript fetch」で検索すると、fetchの使い方を説明したサイトが見つかりますので、調べてみてください。

fetch

Javascriptで「fetch」を使ってWebAPIを呼び出すときは、次のような流れになります。

let url = 'https://xxxxxxxx?a=123&b=456&c=789';    // WebAPIのURLを組み立てる
fetch(url)                                         // fetchを呼びだす
.then(response => response.json())
.then(data => {
  alert(JSON.stringify(data);                      // APIの実行結果を表示する
});

この流れに合わせて、BODIK APIを呼び出してみましょう。

WebAPIのURLを用意する

WebAPIのURLは、APIサーバーのURLとパラメータの組み合わせになります。Javascriptで文字列を組み立てる方法はいくつかありますが、「テンプレートリテラル」が便利です。

let api_server = 'https://wapi.bodik.jp';
let apiname = 'aed';
let url = `${api_server}/${apiname}`;        // 逆シングルクォート(shift+@)で囲む

JSONを表示、整形

Javascriptでは、JSON.stringify()メソッドを使って、Javascriptの辞書や配列などを文字列に変換することができます。

JSON.stringify(data)

このままではわかりづらいので、インデントを付けて整形することができます。

JSON.stringify(data, null, 2)

ブラウザに表示

Javascriptで画面に文字列を表示します。

// 出力するエレメントをIDで取得する
let output = document.getElementById('output');

// エレメントの「innerHTML」に文字列をセットする
output.innerHTML = JSON.stringify(data, null, 2);

プログラム(Ver1)

まとめると次のようになります。
テキストエディタに下記の内容を入力し、「program1.html」と名前を付けて保存してください。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>BODIK API</title>
    <script type="text/javascript">
        let api_server = 'https://wapi.bodik.jp';
        let api = 'aed';
        let api_url = `${api_server}/${api}`;
        fetch(api_url)
        .then(response => response.json())
        .then(data => {
            let output = document.getElementById('output');
            output.innerHTML = JSON.stringify(data, null, 2);
        });
    </script>
</head>

<body>
    <h2>BODIK API program #1</h2>
    <pre id="output"></pre>
</body>

</html>

エクスプローラなどで、このファイルを実行すると、ブラウザが表示され、「data」の内容が表示されます。

「data」の中は次のような形式になっています。

{
  'metadata': {
    'api': 'aed',
    'selectType': 'DATA',
    'totalCount': 27430,
    'count': 10
  },
  'resultsets': {
    'type': 'FeatureCollection',
    'features': [
      {
        'type': 'Feature',
        'properties': {
          'municipalityCode': '12301',
          'ID': '',
          'municipalityName': '北海道三笠市',
           ・・・・・・・
        }
      }
    ]
  }
}

BODIK APIの実行結果の構造は、次のようになります。

data = {
  metadata
  resultsets: {
    features: [    配列
      feature   辞書
      feature   辞書
      ・・・・
    ]
  }
}

featureは次のようになっています。

feature = {
  properties,     # 各種属性情報
  geometry        # 位置情報
}

このデータ構造をJavascriptで解析し、propertiesだけを取り出すには、次のようなプログラムを書きます。

let array = [];                                   # propertiesを入れる配列を用意する
let features = data['resultsets']['features'];    # featuresは配列
for (let feature of features) {                   # 配列は、「for .. of」で回す
  let properties = feature['properties'];         # propertiesは辞書
  array.push(properties);                         # properties部分を配列に入れる
}
alert(JSON.stringify(array));                     # 表示する

プログラム(Ver2)

まとめると次のようになります。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>BODIK API</title>
    <script type="text/javascript">
        let api_server = 'https://wapi.bodik.jp';
        let api = 'aed';
        let api_url = `${api_server}/${api}`;
        fetch(api_url)
        .then(response => response.json())
        .then(data => {
            let output = document.getElementById('output');
            let array = [];
            let features = data['resultsets']['features'];
            for (let feature of features) {
                let properties = feature['properties'];
                array.push(properties);
            }
            output.innerHTML = JSON.stringify(array, null, 2);
        });
    </script>
</head>

<body>
    <h2>BODIK API program #1</h2>
    <pre id="output"></pre>
</body>

</html>

プログラム(完成版)

エラー処理等を追加して完成版となります。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>BODIK API</title>
    <script type="text/javascript">
        try {
            let api_server = 'https://wapi.bodik.jp';
            let api = 'aed';
            let api_url = `${api_server}/${api}`;
            fetch(api_url)
            .then(response => response.json())
            .then(data => {
                if ('resultsets' in data) {
                    let resultsets = data['resultsets'];
                    if ('features' in resultsets) {
                        let features = resultsets['features'];
                        let array = [];
                        for (let feature of features) {
                            let properties = feature['properties'];
                            array.push(properties);
                        }
                        let output = document.getElementById('output');
                        output.innerHTML = JSON.stringify(array, null, 2);
                    } else {
                        alert('not found "features" in data');
                    }
                } else {
                    alert('not found "resultsets" in data');
                }
            })
            .catch(error => {
                alert('Exception in fetch:' + error);
            });
        } catch (error) {
            alert('Exception:' + error);
        }
    </script>
</head>

<body>
    <h2>BODIK API program #1</h2>
    <pre id="output"></pre>
</body>

</html>

お疲れ様でした。