Meteorの基本的なAPIを紹介
前回は、Meteorプロジェクトのディレクトリ構造と、それらがMeteorによって実行時にどのように取り扱われるかを解説しました。それにより、MeteorはクライアントとサーバをどちらもJavaScriptで記述でき、コードの共有も非常に容易だということを明らかにしました。
今回は、「サーバとクライアントのどちらもJavaScriptで書ける」というMeteorの特色を示すような、Meteorの基本的なAPIについて解説します。
MeteorのコアAPI
まずは最も基本的なAPIとして、以下の3つがあります。
- Meteor.is_client
- 現在のコードがクライアント上で実行されている場合はtrue
- Meteor.is_server
- 現在のコードがサーバ上で実行されている場合はtrue
- Meteor.startup()
- アプリケーションの開始後に呼び出される。
前回学んだように、プロジェクト内のclient
やserver
、public
以外の場所にあるJavaScriptコードは、サーバ上でもクライアント上でも実行されます。そして、Meteor.is_client
やMeteor.is_server
といった変数を使用すると、現在のプログラムがサーバ上で実行されているのか、クライアント上で実行されているのかを判定することができるわけです。
また、Meteor.startup()は、クライアント上かサーバ上かにかかわらず、アプリケーションの開始後に呼び出されます。クライアント上ではDOMが構築され、Meteorの初期処理が終わったタイミングで、サーバ上ではプロセスが起動して初期処理が完了したタイミングで呼び出されます。
これらを使用したコード例を以下に掲載します。以下のコードは、Meteor.startup()
内でMeteor.is_client
とMeteor.is_server
を使用して処理の振り分けを行っています(ログに出力するメッセージを変えているだけです)。
サーバ上では、meteor
コマンドを実行したコンソール上にメッセージが表示されます。
クライアント上では、画面が表示された直後にブラウザのコンソールにメッセージが出力されました。サーバとクライアントで全く同じコードが動作しつつ、異なる処理が行われていることがおわかりかと思います。
サンプルは以下からダウンロードできます。
サーバのメソッドをクライアントから呼び出す
Meteor.methods()
を使用すると、サーバ上で定義したメソッドをクライアントから呼び出すことも可能です。
Meteor.methods()
の引数は、メソッド名をキー、関数オブジェクトを値としたJavaScriptオブジェクトになります。以下のコードを見れば一目瞭然です。
上のコードがサーバ上で実行されると、クライアントからの呼び出しが可能なhello()
というメソッドが定義されます。
Meteor.methods()
で定義されたメソッドをクライアントから呼び出すには、Meteor.call()
もしくはMeteor.apply()
を使用します。これらのメソッドの違いは、apply()
は呼び出すメソッドの引数を配列で指定するのに対し、call()
は可変長引数で指定するというものです。また、引数の最後には関数オブジェクトを指定することができ、リモートメソッドの戻り値を受け取るためのコールバック関数を渡すことができます。コールバックは2つの引数を取ります。1つ目はエラーが発生した時のエラーオブジェクト、2つ目は正常終了時の戻り値です。
たとえば、上のhello()
をMeteor.call()
を使用して呼び出すと以下のようになります。
これをMeteor.apply()
を使用して呼び出すと以下のようになります。
簡単なサンプルとともに、Meteor.methods()
の動作を確認してみましょう。まずはHTMLのソースコードから。
このHTMLがブラウザにレンダリングされた結果は以下のようになります。
次に、JavaScriptのソースコードを示します。以下のファイルはプロジェクト直下に保存した(sample3-2/sample3-2.js
)ため、クライアントからもサーバからも実行されます。サーバ上で実行される場合はMeteor.methods()
を使用してhello()
というメソッドを定義し、クライアント上で実行される場合は、「クリック」と書かれたボタンにイベントハンドラを設定しています。イベントハンドラの内部でMeteor.call()
を使用し、サーバ側のhello()
メソッドを呼び出しています。
実行結果は以下のとおりです。ボタンを押すとサーバ上のメソッドが実行され、その結果をコールバックで受け取った後、alert()
で表示しています。
サンプルは以下からダウンロードできます。
リモートメソッドのスタブ
Meteor.methods()
は、実はクライアント側でも呼び出すことができます。クライアント側でMeteor.methods()
を使用すると、サーバサイドのメソッド呼び出しをシミュレートする「スタブ」を作成できます。
作成されたスタブのメソッドは、戻り値や発生した例外が全て無視されるため、呼び出し側のコールバックの引数には常にundefinedが渡されます。こういう動作が何の役に立つのか、筆者はまだいまいち理解できていないのですが、Meteorのドキュメントには「スタブはその副作用のために実行される。スタブは、サーバとのラウンドトリップに伴う遅延なしに、サーバのメソッドが行う動作の結果をシミュレートすることを意図している」とあります。
現在メソッドがスタブとして呼び出されているか否かは、メソッド内でthis.is_simulation
という変数にアクセスすればわかります。
リモートメソッドを並列実行する
Meteor.methods()
で作成したメソッドは、1クライアントにつき、1クライアントあたり同時に1つのメソッドしか実行されません。つまり、リモートメソッドは並列実行されないということです。
リモートメソッド内でthis.unblock()
を呼び出すことで、この挙動を変更することができます。このメソッドを呼び出すと、メソッド呼び出しがブロックされなくなり、メソッドが並列実行されるようになります。これは処理の並列度を高めることになりますが、サーバ側の資源(スレッド)が大量に消費される可能性も伴いますので、注意が必要です。
まとめ
今回は、Meteorの実行環境上で、サーバとクライアントのコードがシームレスに連携するためのAPIを紹介しました。次回からはいよいよ、本格的なアプリケーション開発に必要なMVCアーキテクチャなどに関する説明に入ります。