風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

素人による初心者のためのマッシュアップ事始

そもそもマッシュアップって何?

Wikipedia曰く

マッシュアップ(Mashup)とは、複数のWebサービスのAPIを組み合わせ、あたかも一つのWebサービスのようにする機能のこと。

だそうです。


自分なりの解釈を交えて図示すると、

こんなイメージでしょうか。
つまり、

  1. ユーザからある要求(例:ブラウザによる、URLを指定したウェブページ取得のリクエスト(HTTP GET)など)を受ける。
  2. 1.の要求にみあった応答を作成するのに必要な情報を収集するため、いくつかの他のWebサービスAPIをコールする(要求を出して応答を受け取る)。
  3. 2.の結果を組み合わせて加工した結果を、応答としてユーザに返す。

という機能を指すのだと解釈しています。


そういう意味でいえば、実はWebブラウザもマッシュアップを行っているアプリケーションの一種といえそうですね。
すなわち、

  1. ユーザよりURL指定[要求]。
  2. 指定されたページを取得し、そのページを解釈して、他に必要なリソース(スタイルシート、スクリプト、画像、動画等)を取得[他のWebサービスAPIをコール]。
  3. リソースを組み合わせて加工した結果をユーザに表示[応答]。

という流れです。



マッシュアップ・サービスを作る前の準備

自分の場合ですが、サービスを作る前に、まず以下のことを考えます。

  1. どんなサービスにするか
  2. 必要な情報はどうやって取ってくるか
  3. サービスの設置場所はどこにするか

順にみていくと、

「1. どんなサービスにするか」

大元のアイデアですね。
ただばくぜんと、とにかくマッシュアップ・サービスを作りたい、だけではちょっと雲を掴むような話になってしまいますので、少し具体的に、どんなサービスにしたいかをイメージします。
サービスAから取れるaの情報にサービスBから取れるbの情報を関連づけて加工したら便利なんじゃないか、とか、ユーザからの入力を元にサービスCからcという情報を引っ張ってくれば面白いんじゃないか、とか、そういった発想ですね。


製作者の個性がもっとも問われるところですし、この時点では、何が出来るか、よりも、何がしたいか、を優先したいものです。

「2. 必要な情報はどうやって取ってくるか」

マッシュアップ・サービスが前提ですので、当然もととなる情報を配信する他のサービスが存在するわけですが、さて、その中で必要な情報をどうやってとってくればよいものか。
これは、該当するサービスが提供しているAPI(Application Programming Interface)を利用するわけですが、API仕様はサービスによってさまざまですので、これは利用したいサービスがどのようなAPIを提供しているかを自分で調べるしかありません。また、同じ情報を得るにしても複数のAPIが存在する場合もあります。


APIという用語を使うと特別なもののようですが、そういう訳でもありません。
例えば、Webブラウザで「http://〜」と指定して閲覧することの出来るサイトであれば、そのサービスは「"REST(HTTP GET)"というAPIを備えている」といえます。


RESTという言葉を使いましたが、HTTPプロトコル上でよく使われるAPIの技術(インタフェース種別)として代表的なものには、

  1. REST(Representational State Transfer):リソースに対して、これを特定するURIとGET/PUT/DELETE/POSTといったHTTPプロトコルの標準的なメソッドを用いて、アクセスする技術
  2. RPC(Remote Procedure Call):遠隔手続呼出=プログラム言語の関数/サブルーチン/プロシージャ・コールに相当する機能を遠隔で利用する技術

があるようです。


なんかこう書くと難しそうですね。

  1. は先にも書いたように、Webブラウザで普通に使われています。
    例えばアドレス欄でWebページのURLを指定すると、通常はHTTPプロトコルのGETメソッドを使ってページが取得されます。
  2. は直接目にする機会はあまりありませんが、例えばWindows Live Writerubicast Bloggerといったブログ投稿ソフトの内部では使われていると思います。
    よく耳にするXML-RPCSOAPと言われるプロトコルは、XMLベースで手続名やオプション(引数)等を要求し、HTTPプロトコル上で通信するような作りとなっています(応答もXMLベースで取得されます)。
    一見するとRESTに比べて複雑そうですが、PerlやRubyといった代表的なスクリプト言語ではこれを簡単に扱うためのライブラリが提供されており、通常の関数呼出と変わらない手順で呼び出せる(らしい)ので、Webプログラマには使いやすいのかも。



応答の形態もいろいろありますが。テキストベースなものに限れば

  1. RESTの場合
    1. HTML(ごく一般的なHTMLファイル)
    2. XML(Feed(RSSやAtom)、Amazon Web Service APIの応答など)
    3. JSON、JSONP(JSONはJavaScript(ECMAScript)のオブジェクト表記法をベースにしたもので、JSONPはこれにJavaScriptの関数呼出(コールバック)がついたもの)
  2. RPCの場合
    1. XML(XML-RPCやSOAPの応答)

が代表的でしょうか。


もし、同一の情報を得るのに、応答としてHTMLとXMLが選択出来る場合には、一般にXMLを選択した方がよい場合が多いと思います。
これは、例えば、ブログのトップページに書かれている記事の概要を、HTMLで得る場合と、配信されているFeed(XML)を取得する場合とで比較してみると、

  1. XMLの方が余分な情報が少ない(HTMLはサイドバー等、不要な情報がついていることが多い)
  2. XMLの方がHTMLよりも構造が厳密(HTMLはフレキシブルに記述可能な分、特定の情報の場所を探すのが難しくなる/ページがちょっと書き換えられただけで使えなくなる場合が多い)

という理由からです。


また、特にHTMLファイルとXMLファイルとが転送能力は同程度の別のサーバに置かれているようなケースを考えた場合、大抵はHTMLファイルの方がトラフィックが多くて重い(1.の理由でXMLよりサイズが大きくなるのに加えて、Webブラウザを使うと普通はHTMLファイルの方を取得するのでアクセスが集中する)という理由もあります。


その意味で言えば、RESTを使ったAPIとRPCを使ったAPIの両方がある場合には、(RESTを使用するユーザが多いため)RPC側の方が軽い、という傾向もあるかもしれません(もっとも、REST側はその分能力の高いインフラを使用している場合もあると思いますので、一概にはいえませんが)。

「3.サービスの設置場所はどこにするか」

実際のサービスをどこに置くか、ですが「どこ(環境)」の候補としては、

  1. ローカルアプリケーションにする(文字どおり、PC上等でローカルに動作するアプリケーションを指す。通常のアプリケーションの他、ブックマークレットやユーザスクリプト等も含む)。
  2. 使用しているブログのファイルフォルダに置く(通常、CGIは設置出来ず固定リソースのみになるため、JavaScriptやFlash等を使ったサービスに限られる)。
  3. 専用のサービスを利用する(Google App EngineYahoo!Pipesなど)。
  4. CGIが設置可能なレンタルサーバ・サービスを利用する。
  5. 自前でサーバを用意する。

などが考えられます。


これは極端な話、「1. どんなサービスにするか」と「2. 必要な情報はどうやって取ってくるか」で検討した結果が実装できる環境であるならば、どこでもいいわけですが。


その中で、

  • お手軽さ(無料で使える・開発がしやすそう・メンテナンスがしやすそう、など)
  • 使用可能な言語の得手不得手(どっちでもできるんなら得意なoooを使おう・この環境だとxxxしか使えないからちょっと、とか)
  • 将来的な発展性(今は使わないけど、将来的にデータベースなんかも使いたいな・そのうちすごいアクセス数になるかも、など)

なんかも自分なりに考慮して、選ぶとよいのではないでしょうか。


なお、性能的なものまで意識するのであれば、ボトルネック(サービスの遅延要因)がどこで発生しやすいのか把握しておく必要もあります。
おおざっぱには、以下のような感じでしょうか。

  1. サーバ側が平行して処理可能な最大要求数

    サーバ側の設定・性能(インフラの性能(出入口となるネットワークの転送容量)も含みます)によるので(自前で用意する場合以外)ユーザには制御不可。

    従って、サービスのトラフィックに見合ったサーバ選択が必要。

    ※レンタルサーバの場合は、値段に見合った容量になっているのが普通。

    ※無料で利用出来るGoogle App Engineの場合、Googleのインフラを使えるのが魅力のひとつとなっています。トラフィックに応じて自動スケーリングと負荷分散を行い、「月間約 500 万ページ ビューに対応できる十分な CPU と帯域幅を利用でき」るのだそうです。

  2. 使用する他のWebサービスの応答遅延

    他のWebサービスの性能(と、使用するサーバ〜他Webサービス間のインフラの性能)に依存するため、やはりユーザには制御不可。

    ただし、サーバ側でキャッシュ機能を持つことにより、見かけ上の遅延を少なくするなどの対応がなされている(またはユーザ側でキャッシュの設定が可能な)サービスもある。

    Yahoo!Pipesは、取得した他サービスのページ/Feed等を一定時間キャッシュしている模様(ユーザ側からキャッシュをフラッシュすることはできない)。

    Google App Engineは、memcacheという仕組みにより、ユーザが任意にキャッシュを使用することが可能(キャッシュ容量は指定出来ない(Google側の割当て依存)、フラッシュタイミングは指定可能)。

  3. 加工(通信以外の処理)に要する時間

    サーバの性能、および、アプリケーションの作りに依存。

    サーバの性能は自前のサーバ以外はユーザ側からは制御不可だが、アプリケーションの作りによる改善はユーザの自助努力である程度可能な場合もある。



ここまで読まれた方はお気づきかと思いますが、開発に使うプログラミング言語は何がいい?という話題にはほとんど触れていません。
というのも、自分の場合はそれ程多くの言語を知らない、ということもありますし、

  1. サーバサイドの言語の場合:
    いまどきのスクリプト言語なら大抵のことは出来る気がするし(根拠無し)、標準でインストールされているものをそのまま使えばいいのじゃないかな?レンタルサーバでも、Perl、Ruby、PHPあたりなら入っているでしょ……あ、Google App EngineはPythonのみか…ま、習うより慣れろで。
  2. クライアントサイドの言語の場合:
    ブラウザ上でお手軽にページ遷移なしの機能を…ってことになると、やっぱJavaScriptになっちゃうかなぁ。まぁいいや、好きだし。
    Windowsのアプリケーションも作ってみたいなぁ。JavaとかVisual C#辺りをその内勉強してみようかな(と思いつつ絶賛放置中)。

くらいのゆるいポリシーしか持っていないので。


幸い、今は検索エンジンという強い味方がいるので、まったく知らない言語をいちからやる場合でも入門サイトを探すのにあまり苦労しないと思いますし。基本的な開発方法と書き方さえわかれば、あとは実際のアプリケーションを作りつつ、必要になったらその都度調べる、という方針です。


具体例

自分のとぼしい経験からですが、最近作成したマッシュアップ・サービスを元に、具体的な例をあげてみます。

Hatena::Diary 新着記事一覧取得 API


  1. どんなサービスにするか

    はてなが配信しているはてなダイアリーの新着一覧のフィードは、ブログ名とブログのトップページのURLだけで、実際にどんな記事が書かれたのかわからない。



    じゃあ、新着一覧のFeedから取得したダイアリーのFeedを個別に取得して、そのうちの最新記事のタイトル/URL/概要をFeedで配信するサービスを作ろう。
  2. 必要な情報はどうやって取ってくるか

    新着一覧およびダイアリー毎の最近の記事の情報は、共にはてなが提供しているFeed(RSS)で配信されているので、そのまま使えばいいだろう。
  3. サービスの設置場所はどこにするか

    入力はFeedだけだし、GUIのみで作成出来てプログラムする必要もない、Yahoo!Pipesがお手軽かな。

    API(REST)の引数を変えれば、RSSだけじゃなくてJSON/JSONPでも取得出来るから、後で別のサービス立上げるのにも使えそうだし。

    キャッシュもしてくれる(=一定時間内容が変わらない)のも、この用途にはぴったりだろう(新着はすごい勢いで更新されていくので、はてなからの生データをそのまま使うのはあまり実用的ではないし)。
  4. 必要となった知識など




サイトのはてなブックマーク合計を画像で取得する API

  1. どんなサービスにするか

    個別ページのはてなブックマーク数は画像で表示出来るのに、サイト合計の方は出来ないよな…。



    じゃあ、出来るようにしちゃえ。

  2. 必要な情報はどうやって取ってくるか

    はてなブックマークのヘルプを眺めていたら、被ブックマーク合計数はXML-RPC APIで取ってこれることがわかった。

    それで取ってきた数に該当する画像データを転送してあげればいいよね。
  3. サービスの設置場所はどこにするか

    実は最初は、さくらのレンタルサーバ上・Perlで実装していたんだけれど……安いプランだからか、いまいち応答速度がよくないんだよね。負荷もちょっと気になるし……。



    学習のためと、Googleのインフラ性能をあてにして、Google App Engine上に移植してみるか!
  4. 必要となった知識など




はてなダイアリー − 新着一覧』ページ


  1. どんなサービスにするか

    はてなダイアリーの新着記事の一覧、Feedだけでもいいんだけれど、やっぱりWebブラウザで普通に見えた方がいいよねぇ。過去に遡ってどんどん見ていく、というのもやりたいし。



    よし、それっぽいページを作っちゃえ。

  2. 必要な情報はどうやって取ってくるか

    実はHatena::Diary 新着記事一覧取得 APIで、基本的な下準備は終わっていたりするので、とりあえずできそう(APIコール時のオプションを変えればJSONPで取得できる)。

    ※エントリーの全文表示用のAPIなども追加していますが、詳細は省略。
  3. サービスの設置場所はどこにするか

    動的な情報はすべてJSONPで取得できるようにしているので、実は静的ファイルはどこにおいてもよい。



    まぁ、いまはとりあえず、さくらのレンタルサーバ上に静的ファイルは置いておこうか。
  4. 必要となった知識など

    • JavaScriptの知識
    • HTML、スタイルシート(CSS)の知識






あとがき

先日、「はてなダイアリー − 新着一覧」を公開したおりに、id:matcho226さんよりはてなポイントを送信頂きました。
その際に

プログラミングの知識ゼロの人間はなにをどう、どのくらい知識として手に入れればweb上のものをmashup活用できるようになるのでしょうか。プログラミング言語も多数あってワケワカメです。機会があったら記事にでもしていただけると嬉しいです。

というコメントをいただきまして……うーん、と考え込んでしまいました。
というのも、

  • 確かに自分はプログラミングという意味では多少の経験はあるにはある*1
  • とはいえ、いわゆるWebサービスに関してはずぶの素人もよいところ。
  • っていうか「マッシュアップ(Mashup)」という言葉を初めて知ったのは去年*2だし。数える程しか経験ないよ(苦笑)。
  • こんな自分が、↑のようなテーマで記事を書けるのか?
  • たとえ書けたとして、参考になるのだろうか…?

ということでして。


そんなわけで書くのをためらっていましたが……今回、思い切って記事にしてみました。
自分の乏しい経験と思考過程を書いただけですので、ご期待に添えるかどうかはわかりませんが、ご笑覧ください。

ちなみに、ごく個人的な意見ですが……。

  • ここ1週間前後Google App Engineを使ってみましたが、これはなかなかオススメだと思います。
    無料で使えて、かつGoogleの強力なインフラが使用出来るのが魅力。
    サーバサイドの開発言語がPythonに制限されちゃうのがちょっとあれですど、いちからはじめるならそれ程関係ない気もしますし。
  • クライアントサイドの言語としては、何はともあれJavaScript、かな?とりあえず、ページ遷移させないでいろいろと操作させたいなら、必須かも知れません。ただ(サーバ側がJSONなどをサポートしていないかぎり)クロスドメインなアクセスが出来ないのと、ブラウザ毎の方言がきついのが難点。
  • あと、文字列を扱う際に覚えておくと便利なのが正規表現。多少の違いはあれど、大抵の言語で対応していますし(といっても自分は非常に苦手なんですけどね…)。
  • 単に複数のFeedをかけあわせて別のFeedとして配信する、といった用途なら、プログラムせずにすむYahoo!Pipesもいいですよ。RSSの他JSON(P)も取得できるので、JavaScriptとも相性良し。あとは安定性さえ上がってくれれば(苦笑)。

*1:といってもC言語専門。JavaScriptを趣味でやって、あとはせいぜいPerlをかじった程度

*2:2008年3月頃