ngtokuの日記

主に雑記帳です。SNSではngtokuのID取れなかったんで、別のIDでやってます。

Lambda経由でYOLPを呼んでみる

来週Lambda関係のミーティングがあるので、お試しで。
長い関数になるとnpmでアップロードする事になるが、お試しの短い関数なのでGUIで済ませる。
厳密にはステージングやバージョニングを考慮する必要があるが、お試しなので気にしない。


イメージはこんな感じ
f:id:ngtoku:20181112093324p:plain


2.Lambda関数作成

AWS Lambdaのダッシュボードから「関数の作成」ボタンを押下。
f:id:ngtoku:20181110195510p:plain



"一から作成"のまま、名前は適当に、ロールは既存のものが有るならそれを、無ければ画像を参考にロール名も適当に入れる。
f:id:ngtoku:20181110195652p:plain
その後「関数の作成」ボタンを押下して作成。



関数の中身を実装。内容は以下。

const https = require('https');

exports.handler = function(event, context) {
    var ac = event.ac;
    var gc = event.gc;
    const options = {
      protocol: 'https:',
      host: 'map.yahooapis.jp',
      path: '/search/local/V1/localSearch?detail=full&results=10&start=1&output=json&appid=' + process.env.YOLP_APPID + '&ac=' + ac + '&gc=' + gc,
      method: 'GET',
    };
    const req = https.request(options, (res) => {
        var body = '';
        res.setEncoding('utf8');
        res.on('data', (chunk) => {
            body += chunk;
        });
        res.on('end', () => {
            context.succeed(JSON.parse(body));
        });
    })

    req.on('error', (e) => {
        console.error(`problem with request: ${e.message}`);
    });

    req.end();
}

特に説明は不要だと思うけど、process.env.YOLP_APPIDは画面下部にある環境変数で、YOLPのパラメータは以下参照。
YOLP(地図):Yahoo!ローカルサーチAPI - Yahoo!デベロッパーネットワーク


f:id:ngtoku:20181110203236p:plain

作成したら画面右上の「保存」ボタンを押下。



3.テストデータ作成

「保存」ボタンの左二つ目に有る「テストイベントの選択」から「テストイベントの設定」を選択して、パラメータacとgcに適当な値を入れる。
acは以下参照。
総務省|電子自治体|全国地方公共団体コード
gcは以下参照。
YOLP(地図):YOLP業種コード - Yahoo!デベロッパーネットワーク
以下サンプル。
f:id:ngtoku:20181110201109p:plain



4.テスト実行

「保存」ボタンの左に有る「テスト」を実行し、Execution Resultに店舗情報があることを確認する。
以下サンプル。勝手に店舗情報載せるのもアレなので、スクロールはしていない。
f:id:ngtoku:20181110201324p:plain



5.API作成

Amazon API Gatewayから「+APIの作成」ボタンを押下。
f:id:ngtoku:20181110201450p:plain



新しいAPI のままで、適当にAPI名を入れて「APIの作成」ボタンを押下。
f:id:ngtoku:20181110201631p:plain



APIができたら"アクション"から"メソッドの作成"を選択し、POSTメソッドを作成する。
f:id:ngtoku:20181110201747p:plain



わかりづらいかもしれないが、上画像のチェックマークをクリックすると以下画面になる。
Lambda関数に先ほど作成した関数の名称(入力中に補完してくれる)を入れて「保存」ボタンを押下する。
確認ダイアログが出るが了承する。
f:id:ngtoku:20181110201810p:plain



それから"アクション"から"CORSの有効化"を選択し、デフォルトのまま"CORSを有効にして既存のCORSヘッダーを置換"ボタンを押下。
確認ダイアログが出るが了承する。
f:id:ngtoku:20181110202446p:plain



また"アクション"から"APIのデプロイ"を選択し、画面を参考にステージ名に任意の名称を入れて「デプロイ」ボタンを押下する。
f:id:ngtoku:20181110202604p:plain



これでAPIが解放された、画像で隠してある分がリクエスト先のURLである。
f:id:ngtoku:20181110202654p:plain



6.リクエスト発信ページ作成

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>YOLP via Lambda on API Gateway </title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
    <h4>データ件数は最大10件に絞ってあります。</h4>
    <form id="form" method="post" accept-charset="utf-8" return false>
        <p>
            <label>住所コード(JIS 0402)。先頭5桁</label><br>
            <input class="input is-large" type="text" id="ac" name="ac" value="13103">
            <a href="http://www.soumu.go.jp/denshijiti/code.html" target="_blank">コード値参照先</a>
        </p>
        <p>
            <label>ジャンルコード</label><br>
            <input class="input is-large" type="text" id="gc" name="gc" value="0110">
            <a href="https://developer.yahoo.co.jp/webapi/map/openlocalplatform/genre.html" target="_blank">コード値参照先</a>
        </p>
    </form>
    <button id="searchButton">検索</button>
    <div id="dataCount"></div>
    <ul id="result"></ul>
    <div id="responseData"></div>
    <script type="text/javascript">
        $(function(){
            // Ajax button click
            $('#searchButton').on('click',function(){
                $('#result').empty();
                $('#dataCount').empty();
                // 多重送信を防ぐため通信完了までボタンをdisableにする
                var button = $(this);
                button.attr("disabled", true);
                $('#responseData').html("処理中...");
                // 各フィールドから値を取得してJSONデータを作成
                var data = {
                    ac: $("#ac").val(),
                    gc: $("#gc").val()
                };
                $.ajax({
                    url:'APIのURLは各自で作成したAPIの物を入力',
                    type:'POST',
                    data:JSON.stringify(data),
                    contentType: 'application/json', 
                    dataType: "json", 
                })
                .done( (data) => { // 成功時
                    $('#dataCount').html(data.ResultInfo.Count + "件ヒットしました。");
                    $('#responseData').empty();
                    // レスポンスデータ全体を見たい場合はコメントを外す
                    // $('#responseData').html(JSON.stringify(data));
                    $('#result').empty();
                    $(data.Feature).each(function() {
                        console.log("succedss; " +  this.Name);
                        $('#result').append($('<li></li>').append($('<div></div>').text(this.Name)));});
                })
                .fail( (data) => { // 失敗時
                    $('#dataCount').empty();
                    $('#responseData').empty();
                    $('responseData').html(data);
                })
                .always( (data) => { // 常時
                    button.attr("disabled", false);  // ボタンを再び enableにする
                });
            });
        });
    </script>
</body>
</html>

特に難しいことはしていないので、参照のこと。あえて言うならPOSTデータの中身がJSONになっている事くらい。
APIのURLは各自で作成したAPIの物を入力。
問題なければ以下のようにレスポンスが戻ってくる。
f:id:ngtoku:20181110203046p:plain
めでたしめでたし。