Web APIを使うと個人や一企業での収集が難しいデータが簡単に手に入ります。多くは自社の保有するデータをオープンにするWeb APIが多いですが、中には翻訳や画像変換などの様々な機能をWeb APIとして公開しているものもあります。

こういったWeb APIを複数組み合わせることで、全く新しいアプリを作ることができます(なお、複数のWeb APIを組み合わせることをマッシュアップと言います)。

今回はそんなWeb APIの一つ、ホットペッパーAPIを使ったアプリの開発方法について紹介します。

ホットペッパーAPIの取得について

多くのWeb APIは、利用に際して認証が必要となっています。そうしないと無尽蔵にWeb APIをコールされてサーバに負荷がかかったり、他の利用者に迷惑をかける可能性があるからです。

ホットペッパーAPIも認証が必要な仕組みになっており、各自に配布されるAPIキーでの認証が必要となります。新規登録 | リクルートWEBサービスより取得してください。

アプリの概要

今回は位置情報を使って付近のレストラン情報を収集するアプリを作ってみたいと思います。イメージでは次のようになります。まずトップページがあります。

レストラン取得ボタンを押すと、ホットペッパーAPIからレストラン情報を取得して一覧表示します。

一覧の中から店舗名をタップするとレストランの詳細(今回は住所だけですが)を表示します。

それでは作っていきましょう。

Monacaで開発をはじめる

今回は「Onsen UI V2 JS Navigation」テンプレートをベースにしています。画面遷移(今回は一覧画面と詳細画面)の伴うアプリでは、このテンプレートをベースにするのが良いでしょう。

そしてCordovaプラグインとしてGeolocationをインストールします。このプラグインは標準で提供されていますので誰でもインストール可能です。

HTML5 APIのGeolocationを使うこともできますが、位置情報を取得する度に許可を求める確認ダイアログが出てしまいます。Cordovaプラグインであれば一度許可すれば次からはダイアログが出ません。

追加でjQueryをインストールしたら、準備は完了です。

HTMLについて

まず画面の実装について解説します。

画面遷移するために ons-navigator を使います。page要素は最初に表示するページの名前です。

<ons-navigator id="navigator" page="list.html"></ons-navigator>

一覧画面(list.html)は次のようになります。レストラン取得ボタンと、検索結果を表示する空の #shops を用意しておきます。

<ons-template id="list.html">
  <ons-page id="list-page">
    <ons-toolbar>
      <div class="center">レストラン検索</div>
    </ons-toolbar>

    <div class="content" style="text-align: center">
      <ons-list>
        <ons-list-header>
          <a href="http://webservice.recruit.co.jp/"><img src="http://webservice.recruit.co.jp/banner/hotpepper-s.gif" alt="ホットペッパー Webサービス" width="135" height="17" border="0" title="ホットペッパー Webサービス"></a>
        </ons-list-header>
        <ons-list-item>
          <div class="center">
            <ons-button id="getShops">レストラン取得</ons-button>
          </div>
        </ons-list-item>
        <div id="shops">
        </div>
      </ons-list>
    </div>
  </ons-page>
</ons-template>

最後に一覧からタップした時に遷移する詳細画面(detail.html)です。店名、住所を表示する #shop-name#shop-address を用意しておきます。

<ons-template id="detail.html">
  <ons-page id="detail-page">
    <ons-toolbar>
      <div class="left"><ons-back-button>戻る</ons-back-button></div>
      <div class="center shop-name">レストラン詳細</div>
    </ons-toolbar>

    <div class="content" id="shop-info" style="text-align: center">
      <ons-list class="shop-info-list">
        <ons-list-header>名前</ons-list-header>
        <ons-list-item id="shop-name"></span></ons-list-item>
        <ons-list-header>住所</ons-list-header>
        <ons-list-item id="shop-address"></ons-list-item>
      </ons-list>
    </div>
  </ons-page>
</ons-template>

JavaScriptの実装

では続いてJavaScriptの処理について紹介します。全体のコードは以下の通りです。

YOUR_API_KEYは自分のAPIキーに置き換えてください)

// ホットペッパーAPIのキー
var api_key = "YOUR_API_KEY";

// 検索結果のレストラン一覧を入れます
var shops = [];

// 画面が切り替わる度に呼ばれます
document.addEventListener('init', function(event) {
  var page = event.target.id;

  // 最初の画面を表示した時の処理
  if (page == "list-page") {
    // レストラン取得ボタンを押した時の処理
    $("#getShops").on("click", () => {
      // 現在位置を取得します
      navigator.geolocation.getCurrentPosition((location) => {
        // 検索実行するURL
        var url = `http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=${api_key}&lat=${location.coords.latitude}&lng=${location.coords.longitude}&range=5&order=4&format=json`;
        // Ajax実行
        $.ajax({
          type: 'GET',
          dataType: "json",
          url: url
        }).done((results) => {          
          // 処理が成功した場合
          shops = results.results.shop;
          for (var i = 0; i < shops.length; i++) {
            var shop = shops[i];
            // リストに追加
            $("#shops").append(`<ons-list-item modifier="chevron" class="shop" tappable><span data-shop-id="${i}">${shop.name}</span></ons-list-item>`);
          }
        }).fail((err) => {
          // 処理が失敗した場合
          alert("エラー!");
        });
      }, (err) => {

      });
    });

    // レストラン名をタップした時のイベント
    $(document).on("tap", ".shop span", (e) => {
      // レストランデータを特定
      var index = $(e.target).data("shop-id");
      var shop = shops[index];

      // ページ移動
      var nav = document.querySelector('#navigator');
      nav.pushPage('detail.html', {data: {shop: shop}});
    });
  }

  // 詳細画面を表示した時の処理
  if (page == "detail-page") {
    // レストランデータを表示
    var shop = event.target.data.shop;
    $("#shop-name").text(shop.name);
    $("#shop-address").text(shop.address);
  }
});

各処理内容の詳細について解説していきます。

最初の画面を表示した時の処理

一番最初の画面(#list-page)で行う処理は主に2つです。

  1. レストラン取得ボタンを押したら、ホットペッパーAPIをコールして結果を一覧表示する
  2. 一覧をタップした時に詳細画面に遷移する

レストラン取得ボタンを押したら、ホットペッパーAPIをコールして結果を一覧表示

ボタンが押されたら、 navigator.geolocation.getCurrentPosition を使って位置情報を取得します。

// レストラン取得ボタンを押した時の処理
$("#getShops").on("click", () => {
  // 現在位置を取得します
  navigator.geolocation.getCurrentPosition((location) => {
    // 後述
  });
});

位置情報が取得できたら、位置情報を元にしてホットペッパーAPIにアクセスするためのURLを生成します。詳しくはホットペッパー | APIリファレンス | リクルートWEBサービスにて確認できますが、今回は次のようになります。

// 検索実行するURL
var url = `http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=${api_key}&lat=${location.coords.latitude}&lng=${location.coords.longitude}&range=5&order=4&format=json`;

そしてAjaxを実行します。

// Ajax実行
$.ajax({
  type: 'GET',
  dataType: "json",
  url: url
}).done((results) => {
  // 処理が成功した場合
  // 後述
}).fail((err) => {
  // 処理が失敗した場合
  alert("エラー!");
})

処理が成功した場合、一覧が返ってきますのでリストに反映します。

// 処理が成功した場合
shops = results.results.shop;
for (var i = 0; i < shops.length; i++) {
  var shop = shops[i];
  // リストに追加
  $("#shops").append(`<ons-list-item modifier="chevron" class="shop" tappable><span data-shop-id="${i}">${shop.name}</span></ons-list-item>`);
}

なお、上記のWeb API実行処理はMonaca IDEのプレビュー画面では動作しません。Monacaデバッガーで確認を行ってください。

もしプレビュー画面でも確認をしたいという時には、以下のようにhttps通信を使って、フォーマットにはjsonpを指定してください。

var url = `https://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=${api_key}&lat=${location.coords.latitude}&lng=${location.coords.longitude}&range=5&order=4&format=jsonp`;
// Ajax実行
$.ajax({
  type: 'GET',
  dataType: "jsonp",
  url: url

レストラン名をタップした時の処理

続いて一覧からレストラン名をタップした時の処理についてです。ここではレストラン情報を次の画面に引き渡します。レストラン情報はpushPageの二つ目の引数にdataとして渡します。

// レストラン名をタップした時のイベント
$(document).on("tap", ".shop span", (e) => {
  // レストランデータを特定
  var index = $(e.target).data("shop-id");
  var shop = shops[index];

  // ページ移動
  var nav = document.querySelector('#navigator');
  nav.pushPage('detail.html', {data: {shop: shop}});
});

詳細画面を表示した時の処理

次に詳細画面へ遷移した時の処理についてです。ここでは前の画面から渡されたレストラン情報を表示します。HTML側でid指定している部分に描画するだけです。

// 詳細画面を表示した時の処理
if (page == "detail-page") {
  // レストランデータを表示
  var shop = event.target.data.shop;
  $("#shop-name").text(shop.name);
  $("#shop-address").text(shop.address);
}

Web APIを使うことでアプリの可能性を飛躍的に向上させられます。他にもたくさんのAPIがありますのでぜひアプリ開発に組み込んでみてください。

今回のコードはmoongift/monaca_with_hotpepper_apiにアップロードしてあります。実装時の参考にしてください。