Web API の紹介
まずは API を高い視点から見ていきます — これは何なのか、どう働くのか、あなたのコードでどう使うのか、どういう風に作られているのか? また様々なクラスの API は何なのか、どのような使い方があるのかも見ていきます。
前提条件: | 基本的なコンピューターの知識および利用能力、HTML と CSS の基本的な理解、JavaScript の基本 (第一歩、構成要素, JavaScript オブジェクト). |
---|---|
目的: | API に何ができて、あなたのコードでどう使えばいいのか知ること。 |
API って何?
Application Programming Interfaces (APIs) は、開発者が複雑な機能をより簡単に作成できるよう、プログラミング言語から提供される構造です。複雑なコードを抽象化し、それにかわる簡潔な構文を提供します。
実世界の例として、あなたの家、アパートや他の住処にある電気のコンセントについて考えて下さい。あなたの家で機器を使いたい時には、電源コードのプラグをコンセントに差し込めば事足ります。電源に直接結線したりしないでしょう — そんなのは非効率ですし、あなたが電気工事士でなければ、やってみるには難しいし危険です。
画像提供: 超タコ足コンセント by The Clear Communication People, Flickr より
それと同じことで、そうですね、例えば3次元グラフィックのプログラムを JavaScript や Python のような高レベル言語で書かれた API を使ってやる方が、C や C++ のような低レベル言語から直接コンピューターの GPU やグラフィック機能を叩いてやるよりも、ずっと簡単です。
注記: API という語についてもっと詳しいことは API の用語解説 を参照して下さい。
クライアントサイド JavaScript での API
クライアントサイド API では、実際非常にたくさんのAPIが使えます — それらは JavaScript 言語本体の一部ではなく、あなたにスーパーパワーを与えるべく JavaScript 言語のコアの上に築かれた代物です。それらはおおよそ二つのカテゴリに分けられます:
- ブラウザー API は Web ブラウザーに組込まれていて、ブラウザーやコンピューターの環境の情報を取得し、これを使って役に立つややこしい事を行えるようにするものです。 例えば Geolocation API は位置情報を取得するための簡単な JavaScript 構造を提供するので、例えばグーグルマップにあなたの居場所を表示するような事ができます。裏で実際にはブラウザーは低レベル (例えば C++) の複雑なコードをいくつか使ってデバイスの GPS 機器 (あるいは位置情報を得られる他のなんだか) と通信し、位置情報を取得し、コードから利用できるようにブラウザー環境に情報を戻しています。ですがここでもこの複雑な事柄は API で抽象化され隠蔽されます。
- サードパーティ API はデフォルトではブラウザーに組込まれておらず、普通はコードと情報を Web のどこから読み込まねばなりません。例えば Twitter API を使えばあなたの Web サイトにあなたの最新のツイートを表示するような事が可能になります。Twitter API は、Twitter サービスに特定の情報を要求したりするのに使える特別な構造のかたまりを提供します。
JavaScript と API とその他 JavaScript ツールの関係
ここまででクライアントサイド API とは何か、JavaScript 言語とどう関係しているのかお話しました。もっとはっきりさせるために一度おさらいして、ついでに他の JavaScript ツールがどう関係してくるのかもお話しましょう:
- JavaScript — ブラウザーに組込まれた高レベルスクリプト言語で、Web ページやアプリに機能を実装するのに使えます。Node のようなブラウザー以外の他のプログラミング環境でも使えるのは覚えておいて下さい。
- ブラウザー API — ブラウザーに組込みの JavaScript 言語の上にある構造で、何かの機能をもっと簡単に実装できるようにします。
- サードパーティ API — サードパーティのプラットフォーム (Twitter や Facebook) 上に作られた構造で、それらのプラットフォームの機能を Web ページで利用できるようにします (例えばあなたの最新のツイートをあなたの Web ページに表示する)。
- JavaScript ライブラリ — 多くは、独自の関数 を含んだ一つか複数の JavaScript ファイルで、Web ページにくっつけることでスピードアップしたり共通の機能を書いたりできるものです。例えば、jQuery、Mootools や React がなどが含まれます。
- JavaScript フレームワーク — ライブラリの一階層上にあたり、JavaScript フレームワーク (例えば Angular や Ember) は HTML や CSS に JavaScript、インストールして一から Web アプリケーションを作成するのに使えるその他もろもろの技術がパッケージ化されている場合が多いです。ライブラリとフレームワークの大きな相違点は、「制御の逆転 (Inversion of Control)」にあります。ライブラリのメソッドを呼ぶ時には、開発者がコントロールしています。フレームワークでは、コントロールが逆転します: フレームワークから開発者のコードが呼ばれるのです。
API で何ができる?
モダンなブラウザーではすごい数の API を利用できるので、コードからとてもいろいろな事ができます。 MDN API 索引を見てみればわかると思います。
一般的なブラウザー API
特に、あなたが使うであろう最も一般的なブラウザー API のカテゴリ (このモジュールでとても詳しい所まで網羅していきます) は:
- ブラウザーで読み込んだ文書を操作するための API。一番目にする例は DOM (Document Object Model) API で、 HTML と CSS を操作できます — HTML を作成したり削除したり書き換えたり、動的に新しいスタイルをページに適用したり、などなど。例えばページにポップアップウィンドウが表われたり、何か新しい中身が表示されたりする時、DOM が使われています。この種の API についてはドキュメントの操作でもっといろいろ見られます。
- サーバからデータ取得をする API で Web ページの一部を書き換える事はとてもよく行なわれます。この一見ちょっとした事が、サイトのパフォーマンスや振舞いに巨大なインパクトを与えました — 在庫一覧や新しいお話一覧を書き換えたい時に、サーバからページ全体をリロードする事なしにさくっとできたら、サイトやアプリはずっと反応よく素早く感じられます。これを可能にした API には
XMLHttpRequest
と Fetch API が含まれています。Ajax という言葉を聞いた事があるかもしれませんが、これがこのテクニックの呼び名です。これらの API について サーバからのデータ取得でもっといろいろ見られます。 - グラフィックスを描画したり操作する API は多くのブラウザーがサポートしています — 最も知られているものには Canvas と WebGL があり、HTML の
<canvas>
要素上にあるピクセルデータを書き換えて2次元や3次元のシーンを作成するのに使えます。例えばキャンバス API を使って長方形や円のような形を描いたり、キャンバスに画像を読み込んだり、セピアやグレイスケールといったフィルターを適用したり、あるいは WebGL を使ってライティングやテクスチャを使った3Dシーンを作成したりできます。これらの API はよくアニメーションループを作成する API (window.requestAnimationFrame()
など)や他のものと組み合わせて使われ、アニメやゲームのようなものの表示を定期的に書き換えるようにします。 - 動画と音声の API
HTMLMediaElement
や Web Audio API や WebRTC のような API を使うと、 マルチメディアを使ってとても面白い事ができます。音声や動画再生のための独自のコントロールUIの作成、字幕やサブタイトルのような音声トラックをビデオと一緒に表示したり、Web カメラの画像を取り込んで操作し、上述のキャンバスに表示したり Web カンファレンスに参加している他の誰かのコンピューター上に表示したり、音声トラックにイフェクト(ゲイン、ディストーション、音場効果など)をかけたりできます。 - デバイス API は基本的に Web アプリで使えるような形で、今時のハードウェアデバイスのデータを操作したり取得する API です。デバイスの位置データにアクセスして地図上にあなたの居場所を書くような位置情報 API についてはすでにお話しました。他の例にはシステム通知を使って Web アプリに役に立つアップデートがあるのを知らせたり(Notifications API を参照)、ハードウェアを振動させたり(Vibration API を参照)などがあります。
- クライアント側でのデータ保持 API は今多くのブラウザーに普及しつつあります。— クライアント側にデータを保存できると、ページを移動しても状態を保存したり、たとえデバイスがオフラインでも動作するようなアプリを作成したいような場合、とても役に立ちます。いくつもの選択肢があり、例えば Web Storage API を使ったキーバリューストアや、 IndexedDB API を使ったもっと複雑なテーブル型データ保存などです。
一般的なサードパーティ API
サードパーティ API はバラエティーに富んでいます。あなたが遅かれ早かれ使うようになりそうな、世間でよく使われているものには以下のようなものがあります:
- Twitter API、あなたの最新のツイートをあなたの Web サイトに表示したりするような事に使えます。
- Mapquest や Google Maps API のような地図の API は、あなたのWebページ上に地図を使ったあらゆる事を可能にします。
- Facebook APIスイートによって Facebook エコシステムの様々な部品を使ってあなたのアプリを強化できます。例えばアプリへのログインを Facebook のログインで行なったり、アプリ内での支払い、ターゲット広告を出したりなどです。
- Telegram APIs を使用すると、ボットのサポートに加えて、Telegram チャネルのコンテンツを Web サイトに埋め込むことができます。
- YouTube API を使ってあなたのサイトに YouTube のビデオを埋め込んだり、YouTube を検索したり、プレイリストを作成したりなどなどできます。
- Pinterest API は、Pinterest のボードとピンを管理して Web サイトに含めるためのツールを提供します。
- Twilio APIはあなたのアプリで音声・ビデオ電話の機能を作成したり、SMS/MMSを送信したりなどするためのフレームワークを提供します。
- Mastodon API を使用すると、Mastodon ソーシャルネットワークの機能をプログラムで操作できます。
注記: サードパーティ API については Programmable Web API directory でもっと多くの情報を見られます。
API はどのように動作する?
異なる JavaScript APIはそれぞれに違う方法で動作しますが、普通は、共通した機能とどのように動くべきかの類似したテーマを持ちます。
オブジェクトに基づいています
あなたのコードは一つ以上の JavaScript オブジェクトを通じて API とやりとりし、オブジェクトは API が使用するデータ (オブジェクトのプロパティとして持つ) や API が提供する機能(オブジェクトメソッドとして持つ) の容れ物として使われます。
注記: もしまだオブジェクトがどのように動作するかについて理解があやふやなら、先に進む前に JavaScript オブジェクト モジュールを読みなおし、練習するのをおすすめします。
Web Audio API の例に戻ってみましょう。Web Audio API はとても複雑な API で、たくさんのオブジェクトから成り立っています。わかりやすいものでいうと下記が挙げられます:
AudioContext
は、ブラウザー内で再生する音声を操作するのに使われるオーディオグラフを表し、その音声を操作するためのたくさんのメソッドとプロパティを持ちます。MediaElementAudioSourceNode
(en-US) は、音声コンテキストの中で再生または操作したい音声を含む<audio>
要素を表します。AudioDestinationNode
は、音声の最終目的地、つまりはコンピューターで実際に出力するデバイス(通常スピーカーやヘッドホン)を表します。
では、どのようにこれらのオブジェクトは互いに作用するのでしょうか? こちらのシンプルな web audio の例 (デモページ)を見ると、最初に以下のような HTML が書かれています。
<audio src="outfoxing.mp3"></audio>
<button class="paused">Play</button>
<br>
<input type="range" min="0" max="1" step="0.01" value="1" class="volume">
最初に、 <audio>
要素を記述してページに MP3 を埋め込みます。デフォルトのブラウザーのコントロールは記しません。次に音楽を再生・停止させるのに使う <button>
、再生中の音楽の音量を調整するのに使う range タイプの <input>
要素を記述します。
次にこの例の JavaScript を見てみましょう。
まず、トラックを操作するための AudioContext
インスタンスを作成します。
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();
次に、 <audio>
、 <button>
、および <input>
要素への参照を格納する定数を作成し、 AudioContext.createMediaElementSource()
メソッドを使用して、音声のソースを表す MediaElementAudioSourceNode
を作成します。<audio>
要素はここから再生されます。
const audioElement = document.querySelector('audio');
const playBtn = document.querySelector('button');
const volumeSlider = document.querySelector('.volume');
const audioSource = audioCtx.createMediaElementSource(audioElement);
次に、ボタンが押されたら再生と停止を切り替えるイベントハンドラーと、曲が再生し終わったら最初に戻るイベントハンドラーを記述します。
// play/pause audio
playBtn.addEventListener('click', function() {
// check if context is in suspended state (autoplay policy)
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
// if track is stopped, play it
if (this.getAttribute('class') === 'paused') {
audioElement.play();
this.setAttribute('class', 'playing');
this.textContent = 'Pause'
// if track is playing, stop it
} else if (this.getAttribute('class') === 'playing') {
audioElement.pause();
this.setAttribute('class', 'paused');
this.textContent = 'Play';
}
});
// if track ends
audioElement.addEventListener('ended', function() {
playBtn.setAttribute('class', 'paused');
playBtn.textContent = 'Play';
});
Note: 気づいた方もいるかも知れませんが、音声を再生・停止する play()
と pause()
メソッドは Web Audio API の一部ではなく、 HTMLMediaElement
API の一部です。これらは異なりますが密接に関連しています。
次に、 BaseAudioContext.createGain
を使用して GainNode
(en-US) オブジェクトを作成します。このオブジェクトを使用して音声全体の音量を調整し、スライダーの値が変更される度にオーディオグラフのゲイン(音量)の値を変更する別のイベントハンドラーを作成します。
const gainNode = audioCtx.createGain();
volumeSlider.addEventListener('input', function() {
gainNode.gain.value = this.value;
});
これを機能させるために最後に行うことは、オーディオグラフ内のさまざまなノードを接続することです。これは、すべてのノードタイプで使用可能な AudioNode.connect()
(en-US) メソッドを使用して行われます。
audioSource.connect(gainNode).connect(audioCtx.destination);
音声はソースから始まり、ソースはゲインノードに接続されるため、音声の音量を調整できます。次に、ゲインノードが宛先ノードに接続され、コンピューターでサウンドを再生できるようになります。(BaseAudioContext.destination
は、スピーカーなど、コンピューターのハードウエアで使用可能なデフォルトの AudioDestinationNode
を表します。)
認識できる入口があります
API を使うときは、その API の入口がどこなのかしっかり確認するべきです。Web Audio API ではとても単純でした — それは AudioContext
オブジェクトであり、あらゆる音声操作を行うために使用する必要があります。
Document Object Model (DOM) API でも単純な入口があります — これの機能は Document
もしくは何らかの方法で影響を与えたい HTML 要素のインスタンスにぶらさがっている場合が多く、例えば:
const em = document.createElement('em'); // create a new em element
const para = document.querySelector('p'); // reference an existing p element
em.textContent = 'Hello there!'; // give em some text content
para.appendChild(em); // embed em inside para
Canvas API は、諸々を操作するために使用するコンテキストオブジェクトの取得にも依存していますが、この場合は、音声コンテキストではなく描画コンテキストです。そのコンテキストオブジェクトは、描画をしたい <canvas>
要素への参照を取得して、 これの HTMLCanvasElement.getContext()
(en-US) メソッドを呼ぶと作成されます:
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
キャンバスを使って何かやろうとする場合は何でも、コンテキストオブジェクト (これは CanvasRenderingContext2D
のインスタンスです) のプロパティやメソッドを呼んで行ないます。例えば:
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
ctx.fill();
};
状態の変化を捉えるのにイベントを使います
すでに学習コース中でイベントについてはお話しています、イベントの紹介 — この記事でクライアント側 Web イベントとは何か、コードの中でどのように使えるのか詳しく見てきました。もしまだクライアント側 WebAPI の仕組みがよくわからいなら、この先に進む前に記事を読み直しておく方が良いでしょう。
イベントを持たない WebAPI もありますが、ほとんどの WebAPI はいくつか持っています。イベントが発火した際に関数を実行できるイベントハンドラーのプロパティについては、リファレンス記事の独立した"イベントハンドラー"セクションとしておおよそ列挙されています。
上記の Web Audio API の例では、すでにいくつかのイベントハンドラーが使用されています。
別の例として、XMLHttpRequest
オブジェクトのインスタンス (一つ一つがサーバから何らかの新しいリソースを取得しようとするHTTPリクエストを表わします) にはとてもたくさんのイベントが付随しており、たとえば load
イベントは発火したリソースに対する正常なレスポンスが返ってきて、それが使えるようになった時点で発火します。
次のコードはこれをどう使うのか示す簡単な例です:
let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
let request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'json';
request.send();
request.onload = function() {
const superHeroes = request.response;
populateHeader(superHeroes);
showHeroes(superHeroes);
}
最初の 5 行で取得したいリソースを指定し、XMLHttpRequest()
コンストラクタを使って新しいリクエストオブジェクトを生成し、指定のリソースを取得するために GET
リクエストを作り、レスポンスを JSON 形式として吐き出すよう指定、そしてリクエストを送信します。
onload
ハンドラー関数で私たちがレスポンスに対して何を行なうかを指定します。load イベントが発火した後には、レスポンスが正常に得られて利用できるようになっている (エラーは起きていない) とわかっていますので、JSON であるレスポンスを superHeroes
変数に保存し、以降の処理のために 2 つの異なる関数に引き渡しています。
必要なところには追加のセキュリティ機構があります
WebAPI 機能は JavaScript や他の Web 技術と同等のセキュリティ上の配慮が必要です (例えば same-origin ポリシー) が、追加のセキュリティ機構が必要な場合もあります。例として今時の WebAPI の中には HTTPS で配信されるページ上でしか動かないものがあり、これは機密とすべきデータをやりとりする可能性があるためです (ServiceWorkers や Push など)。
さらには、ある種の WebAPI への呼び出しがあなたのコードにあると、ユーザに対してそれの許可を要求します。例えば、Notifications API (通知 API) はポップアップのダイアログボックスを用いて許可を要求します:
Web Audio および HTMLMediaElement
API には、自動再生 (autoplay) ポリシー (en-US) と呼ばれるセキュリティ機構が適用されます。これは、基本的に、ページの読み込み時に音声を自動的に再生できないことを意味します。ユーザーに次のことを許可する必要があります。ボタンのようなコントロールを介して音声再生を開始します。これは、音声の自動再生は通常非常に煩わしいものであり、ユーザーにそれを課すべきではないためです。
注記: ブラウザーの厳格さによっては、このようなセキュリティ機構により、例がローカルで機能しなくなる場合があります。つまり、ローカルの例のファイルをウェブサーバーから実行するのではなく、ブラウザーに読み込んだ場合です。執筆時点では、Web Audio API の例はローカルでは Google Chrome で動作しません。動作する前に、GitHub にアップロードする必要がありました。