2012年8月10日

プログラミング

JSONP WebAPIを爆速で使いこなせるフレームワーク

  • このエントリーをはてなブックマークに追加

Yahoo!デベロッパーネットワークの中野(@Hiraku)と申します。 「WebAPIの魅力を存分に宣伝せよ」という使命を受けまして、これから何度かTechblogを書くことになります。以後、お見知りおきを。

さて、Yahoo! JAPANが公開しているWeb APIはたくさんありますが、JSONPに対応しているものがいくつかあります。ショッピングオークションYOLP震災関連情報などです。

JSONPについて詳しくは過去記事を見てください。

他の形式に比べると、サーバーを準備しなくてもブラウザーだけで動かすことができ、古いブラウザーでも動くという、JSONPにしかないメリットがあります。夢のような形式!なのです。

…そのはずなんですが、解説記事を読んでも、まだまだ使うのが難しいと思いませんか? そもそも、JavaScriptを書くというのは大変なことです。

  • 「JavaScriptなんて面倒くさい。」
  • 「プログラミング…! 難しそう…」
  • 「HTMLなら書けるんだけどなあ…」

そんな方のために、「HTMLさえ書ければJSONPのWebAPIを使いこなすことができるフレームワーク」を用意しました。

「JSONP WebAPIを使った開発を爆速にする」の意味で、名付けて爆速JSONPです!

使い方は簡単

こんなHTMLを書いて、「setsuden.html」などの名前で保存してください。bodyタグの中にはscriptタグが一つ、書いてあるだけです。

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>爆速JSONP</title>
</head>
<body>
 
<script src="http://i.yimg.jp/images/yjdn/js/bakusoku-jsonp-v1.js"
  data-url="http://setsuden.yahooapis.jp/v1/Setsuden/latestPowerUsage"
  data-p-appid="APPLICATION_ID"
  data-p-output="json"
  >
現在の電力消費量は{{ElectricPowerUsage.Usage.$}}kWです。
</script>
 
</body>
</html>

おっと、Yahoo! JAPANのWebAPIを使う場合はデベロッパーネットワークアプリケーションIDを取得する必要があります。 APPLICATION_ID と書かれている場所は、取得したアプリケーションIDで置き換えてください。

setsuden.htmlができあがったら、ダブルクリックしてブラウザーで開いてみてください。

「現在の電力消費量は○○kWです。」と、数字が表示されたらおめでとうございます。あなたは今WebAPIを使ったことになります。

ようこそ! WebAPIハッカーの世界へ!

処理の流れ

もう少し丁寧に 爆速JSONP が行っていることを説明すると、

  • WebAPIにリクエストして、データを取得
  • データをmustache.js(外部サイト)のテンプレートにはめ込んでHTMLを作成する
  • 最後にscriptタグ自身と出来上がったHTMLを置き換える

この3つになります。

逆に言うとこれだけしか行いません。複数のAPIの結果を使ったり、フォームの入力内容でリクエストするなど、難しいことはできません。しかし、JavaScriptをほとんど書かずにWebAPIのレスポンスをHTMLとして埋め込むことができます。要は、ありとあらゆるJSONPのWebAPIをブログパーツ化することができるのです。

mustache.jsという単語が出てきましたが、あとで解説いたします。

WebAPIをブログパーツ化してみよう

爆速JSONPを使って、もう少しデザインに凝ったブログパーツを作る流れを説明いたします。

先ほどの例では、電力使用状況APIの、「消費量」の部分を表示しただけです。これを節電・停電 - Yahoo! JAPANのように、割合で表示してみましょう。

単にWebAPIのレスポンスを表示してみる

以降、HTMLを全て表示していると読みにくくなりますので、scriptタグの部分だけ記載します。先ほどのsetsuden.htmlを引き続き編集してブラウザーをリロードしているつもりでご覧ください。

WebAPIを使いこなすには、まずWebAPIから何が返されたのか把握する必要があります。爆速JSONPでは、テンプレートの部分を空にするとデバッグモードになり、レスポンスを全て表示します。

<script src="http://i.yimg.jp/images/yjdn/js/bakusoku-jsonp-v1-min.js"
  data-url="http://setsuden.yahooapis.jp/v1/Setsuden/latestPowerUsage"
  data-p-appid="APPLICATION_ID"
  data-p-output="json"
  ></script>

これを実行すると、電力使用状況APIのレスポンスがインデントされて表示されます。

{
  "ElectricPowerUsage": {
    "Area": "tokyo",
    "Usage": {
      "@unit": "kW",
      "$": 45580000
    },
    "Capacity": {
      "@unit": "kW",
      "$": 53410000
    },
    "Date": "2012-07-25",
    "Hour": 14
  }
}

色々とデータが返ってきていることがわかりますね。実際にどの部分が何を示しているかは、電力使用状況APIのドキュメントをご覧ください。

※デバッグモードのみ、JSONオブジェクトを使っているため、最新のブラウザーでないと動きません。

パラメータを変えてみる

勘のいい方はお気づきかもしれませんが、data-urlでWebAPIのURLを指定し、data-p-で始まる属性で、WebAPIにパラメータを渡すのが爆速JSONPの文法です。

ちゃんとWebAPIにリクエストをしていることを確認するため、パラメータをひとつ追加してみましょう。scriptタグにdata-p-area="kansai"という属性を追加すると、関西電力の電力使用量に変わります。(電力使用状況APIの仕様では、areaパラメータなしの場合、東京電力の電力使用量が返ります。)

<script src="http://i.yimg.jp/images/yjdn/js/bakusoku-jsonp-v1.js"
  data-url="http://setsuden.yahooapis.jp/v1/Setsuden/latestPowerUsage"
  data-p-appid="APPLICATION_ID"
  data-p-area="kansai"
  data-p-output="json"
  ></script>

↓ブラウザで表示してみると

{
  "ElectricPowerUsage": {
    "Area": "kansai",
    "Usage": {
      "@unit": "kW",
      "$": 21400000
    },
    "Capacity": {
      "@unit": "kW",
      "$": 26190000
    },
    "Date": "2012-07-29",
    "Hour": 17
  }
}

レスポンスの「Area」の項が「tokyo」から「kansai」に変わりましたね。こんな風にパラメータとURLを調整していきます。

テンプレートを書く

さて、デバッグモードでレスポンスを見るのにもだんだん飽きてきた頃ではないでしょうか。HTMLで出力していきましょう。

爆速JSONPはMustacheというテンプレートエンジンを内包しており、この文法でテンプレートを書きます。

JavaScript用のテンプレートエンジンは他にもいくつかありますが、Mustacheは簡潔・軽量を特徴としています。要は機能が少ないので、覚えることも少なくて済みます。

最初に例を書きましたが、{{}}で囲われた部分がパラメータで、WebAPIのレスポンスに置き換わります。

<b>{{ElectricPowerUsage.Usage.$}}</b>
 
<!-- ↓出力結果例 -->
 
<b>21400000</b>

レスポンスが入れ子構造になっているときは、「.」(ドット)で繋げることで下層の要素を表します。

また、{{#someLabel}}{{/someLabel}}で囲うことで、ブロック内ではsomeLabel.を省略することができます。

例えば、電力使用状況APIのレスポンスを上から順に表示しようとした場合、素直に書くとテンプレートが煩雑になります。

<ul>
 <li>{{ElectricPowerUsage.Area}}</li>
 <li>{{ElectricPowerUsage.Usage.$}}</li>
 <li>{{ElectricPowerUsage.Capacity.$}}</li>
 <li>{{ElectricPowerUsage.Date}}</li>
 <li>{{ElectricPowerUsage.Hour}}</li>
</ul>

ブロックを使うと、Electri…と何度も入力しなくてもよくなります。

{{#ElectricPowerUsage}}
<ul>
 <li>{{Area}}</li>
 <li>{{Usage.$}}</li>
 <li>{{Capacity.$}}</li>
 <li>{{Date}}</li>
 <li>{{Hour}}</li>
</ul>
{{/ElectricPowerUsage}}

この他にも配列の繰り返しなど、Mustacheには便利な機能がありますが、詳細は公式マニュアル(外部サイト)をご覧ください。

データの加工

ここまでで、WebAPIのレスポンスを表示できるようになりました。

しかし、今回のゴールは電力使用状況を割合で表示することです。割合はWebAPIのレスポンスに含まれていないため、自分で計算する必要があります。

爆速JSONPでは、レスポンスを受け取ってからその結果をMustacheに渡すまでの間に、一度だけ任意の関数でデータを加工する機能を持っています。

ここからは、残念ながら少しだけJavaScriptを書く必要があります。。

まずは、データ加工用の関数を定義します。テンプレートより手前にもう一つscriptタグを書いて、そこに関数を定義しましょう。そしてテンプレート側にdata-filter=というパラメータを追加し、今定義した関数の名前を入力しておきます。

<script>
/**
 * データの加工をする関数
 */
function calculateRate(data) { //APIのレスポンスが渡される
  data.additional = "追加情報";
  return data; //ここで返すデータが、本来のAPIレスポンスの代わりに利用される
}
</script>

<script src="http://i.yimg.jp/images/yjdn/js/bakusoku-jsonp-v1.js"
  data-url="http://setsuden.yahooapis.jp/v1/Setsuden/latestPowerUsage"
  data-p-appid="APPLICATION_ID"
  data-p-output="json"
  data-filter="calculateRate"></script>

<!-- ↑data-filterで加工に使いたい関数名を指定 -->

<!-- ... -->

こうすると、デバッグ表示されるレスポンスに「additional」という要素が追加されるはずです。こんな風にfilterを使ってデータを追加したり、データの数字によって出し分けをするなど、様々なことが可能です。

完成!

おおよそ説明できましたので、「Usageの値をCapacityで割って割合を出す」「電力使用状況がピンチなら文字を赤くする」などの工夫をfilterに加えて、ここまでの内容を全部まとめてみました。

実行イメージ
<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>ブログパーツサンプル</title>
 </head>
 <body>
 
<script>
/**
 * データの加工をする関数
 */
function calculateRate(data) {
  var e = data.ElectricPowerUsage;
  e.Rate = Math.round(e.Usage.$ / e.Capacity.$ * 1000) / 10;
 
  if (e.Rate > 90) {
    e.Color = 'red';
  } else if (e.Rate > 80) {
    e.Color = 'orange';
  } else {
    e.Color = 'green';
  }
  return e;
}
</script>
 
<script src="http://i.yimg.jp/images/yjdn/js/bakusoku-jsonp-v1-min.js"
  data-url="http://setsuden.yahooapis.jp/v1/Setsuden/latestPowerUsage"
  data-filter="calculateRate"
  data-p-appid="APPLICATION_ID"
  data-p-output="json"
>
 
 <small>東京電力:電力使用量<br>
 {{Date}} {{Hour}}時現在
 </small><br>
 <strong style="color:{{Color}};font-size:3em;font-family:sans-serif;">
  {{Rate}}
 </strong>
 %<br>
 節電にご協力ください
 
</script>
 
 </body>
</html>

それなりにブログパーツ風になりました。

カスタマイズできるブログパーツと言うと、大抵は用意されたデザインの中から選ぶだけのものがほとんどです。

しかし爆速JSONPとWebAPIから作ると、HTMLを完全カスタマイズできます。この自由度は、ただのブログパーツとは比較になりません。ぜひ、ぐりぐり書き換えて、もっとリッチな作品を作っていただければと思います。

そのほかの例

JSONPは他にショッピングAPIオークションAPIが対応しています。爆速JSONPを使えば、人気のコスプレ衣装を表示するのもこの通り簡単です。

<script src="http://i.yimg.jp/images/yjdn/js/bakusoku-jsonp-v1-min.js"
  data-url="http://shopping.yahooapis.jp/ShoppingWebService/V1/json/categoryRanking"
  data-p-appid="APPLICATION_ID"
  data-p-category_id="14828"
  data-p-type="up">
<ol>
{{#ResultSet.0.Result}}
{{#0}}
  <li><a href="{{Url}}"><img src="{{Image.Medium}}"><br>{{Name}}</a></li>
{{/0}}
{{#1}}
  <li><a href="{{Url}}"><img src="{{Image.Medium}}"><br>{{Name}}</a></li>
{{/1}}
{{#2}}
  <li><a href="{{Url}}"><img src="{{Image.Medium}}"><br>{{Name}}</a></li>
{{/2}}
{{/ResultSet.0.Result}}
</ol>
</script>

ここでは行っていませんが、アフィリエイトにも対応していますので、ぜひ挑戦してみてください。

爆速JSONPのご利用について

こちらを直接埋め込む形でご利用になれます。

今のところ、Yahoo! JAPANのソフトウェアガイドラインに則るかたちでのご利用をお願いいたします。爆速JSONPはMITライセンスで提供しています。 Yahoo!デベロッパーネットワークのWebAPIを利用する場合は、API自体に利用制限がありますので、ご注意ください。

他社のWebAPIや、自作サービスのWebAPIと組み合わせてご利用いただくことも可能です。

なお、内包しているMustache.jsはMITライセンスですので、そちらもご注意ください。

ただ、もっと自由なライセンスの方が使いやすいと思います。ビルドスクリプトなど含め、オープンソースソフトウェアとして公開できるよう調整中です。もう少々お待ちください。


追記

2012年9月11日(火)

  • 爆速JSONPを複数回読み込んだ際、動かなくなるバグがあったので修正しました。
  • JSONPに対応していないWebAPIに関しては、続編の「爆速YQL」をご利用ください。

2013年2月14日(木)

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加