特集:Windows開発者のためのNode.js入門 勢いで始めてみるNode.js Webアプリ開発 デジタルアドバンテージ 一色 政彦2012/06/15 |
![]() |
Page1
Page2
|
■初めてのNode.jsによるWebアプリ開発
●ひな型ファイルの確認
Node.jsのテンプレートから自動作成されたひな型のファイル群を確認してみよう。
WebMatrix 2の左下にあるメニューで[ファイル]を選択すると、左上に現在のプロジェクトに含まれるファイル群がツリー表示される(次の画面を参照)。
![]() |
Node.jsのテンプレートから自動作成されたひな型のファイル群 |
一番重要なのは、「server.js」というファイルである。そのコード内容については後で詳しく説明するが、その前に主なファイルの内容を箇条書きで紹介しておく。
- server.js: Webサーバ(HTTPサーバ)を動かす。
- HTMLPage.html: ひな型のHTMLファイル。現時点で使われていないが、後述のサンプルで使用する。
- web.config: IIS/IIS Expressの背後でNode.js用プロセスを実行するための設定が記述されている。この中で、「server.js」ファイルがNode.jsアプリケーションとして、またpublicフォルダ内はスタティックとして宣言されている。
- robots.txt: 検索エンジンのクローラ向けのファイル。中身は空。
- favicon.ico: サイトのアイコン。仮のもの。
- publicフォルダ: この中のファイルはスタティック・ファイルとして配信できるので、.jsファイルや.cssファイルを配置するとよい。配置したファイルには、「public」というフォルダ名を入れずに、「http://localhost:13506/example.txt」のような形でアクセスできる。
- server.js.debub/server.js.logsフォルダ: ひな型状態では本来は存在しない(筆者が少しデバッグ関連を試したので生成された)。Node.jsで使うデバッグやログ用のフォルダで、Webアプリ内で使うものではない。
つまり、付属するファイルはたくさんあるが、ひな型のNode.jsプログラミング関連のファイルは「server.js」ファイルしかない。これを開くと、次のような5行のコードになっている。
|
|
最もシンプルなWebアプリのコード(server.js) |
コード内容を説明していこう。
○「var http = require('http');」
Node.jsでは「モジュール」という形で、さまざまな機能を読み込める。ここでは、「http」という文字列を引数に指定したrequire関数を呼び出すことで、httpモジュールを読み込んでいる。
○「http.createServer(...)」
httpモジュールのcreateServer関数を呼び出して、http.Serverクラスのオブジェクトを作成している。
○「function (req, res) {...}」
createServer関数の引数として、requestイベントを処理するコールバック関数が指定されている。「req」は、HTTPリクエストを表すhttp.ServerRequestクラスのインスタンス、「res」は、HTTPレスポンスを表すhttp.ServerResponseクラスのインスタンスである。
○「res.writeHead(200, { 'Content-Type': 'text/html' });」
resオブジェクトのwriteHead関数を使って、ステータス・コード「200」とHTTPヘッダ「Content-Type: text/html」を引数に指定して、レスポンス・ヘッダを送信している。
○「res.end('Hello, world!');」
resオブジェクトのend関数を使って、「Hello, world!」というデータの送信とともに、レスポンスのヘッダとボディの送信完了を伝達している。
○「.listen(process.env.PORT || 8080);」
createServer関数の戻り値はhttp.Serverオブジェクトである。そのlisten関数を使って、指定されたポート番号(※「process.env.PORT」はユーザー環境のポート番号)でのコネクションの受け入れを開始する。つまり、この時点から、上記のプログラム内容が動作することになる。
●HTMLファイルを動的に表示するサンプルのコード
以上でひな型は理解できたので、ここからは実際のコーディングを楽しもう。まずは、既存のHTMLPage.htmlファイルをテンプレートとして利用してみることにする。
Node.jsで使えるモジュールや、その中のクラスと関数を調べるには、以下に示すNode.js公式サイトにあるリファレンスが便利である。
このリファレンスの目次を見ると、「ファイル・システム」のモジュール(fs)が、ファイルの読み込みに使えそうである。
HTMLPage.htmlファイルを読み込んで、その内容をそのままレスポンスとして返す処理を書き加える。そのコードは、次のようになった。
|
|
HTMLPage.htmlファイルの内容をそのまま返すWebアプリのコード(server.js) | |
※サンプル用なのでエラー処理は省略した。 |
このコードで、追記/修正したのは、主に次の2行だ。
○「fs.readFile('./HTMLPage.html', 'UTF-8', function(err, data) { ... });」
fsモジュールのreadFile関数を使って、「./HTMLPage.html」ファイルの内容を、「UTF-8」文字コードで読み込んでいる。この処理も非同期になっており、処理完了後に第3引数に指定されているコールバック関数が呼び出される。その関数内に(つまりファイル・データの読み込み完了後に)、前述のレスポンス・ヘッダやデータの送信処理を移した。
○「res.end(data);」
resオブジェクトのend関数を使って、ファイル・データの送信とともに、レスポンスのヘッダとボディの送信完了を伝達している。
●HTMLファイルを動的に表示するサンプルの実行
それでは実行して正常に動作するかを確かめてみよう。
WebMatrix 2の上部にある([ホーム]タブ内の)[実行]ボタンをクリックすると、ローカル環境でNode.jsのWebアプリがブラウザで表示される。HTMLPage.htmlファイルには、必要最小限のタグしか含まれていないので真っ白なページが表示される。HTMLPage.htmlファイルの<body>タグ内に「こんにちは、世界!」などと適当な文字列を書き込んで、[Ctrl]+[S]キーでファイルを保存して、ブラウザをリロードしてみると、その書き込み内容が確かに表示されるのを確認できる。以下の画面はその例だ。
![]() |
HTMLPage.htmlファイルに何か追記して、ブラウザをリロード |
![]() |
![]() |
追記した内容が表示された |
HTMLPage.htmlファイルをそのまま返すWebアプリの実行例 |
●HTMLファイルをテンプレートとして扱うサンプル
次に、このHTMLPage.htmlファイルをテンプレートとして利用するためのコードを記述しよう。
今回のテンプレート・ファイルには、以下のようなプレイスホルダ(=置き換え対象となる目印)を設定できるようにする。
- 「@@title@@」: Webアプリ・タイトルを設定するためのプレイスホルダ。
- 「@@content@@」: Webアプリのメイン・コンテンツを設定するためのプレイスホルダ。
実際のファイル内容は次のとおり。
|
|
各プレイスホルダを設定した場合のHTMLコード(HTMLPage.html) |
ここではテスト用のデモとして、「@@title@@」プレイスホルダを「Thumbla」という文字列に、「@@content@@」プレイスホルダを「<p>ここがメイン・コンテンツです。</p>\r\n<p>コンテンツは動的に生成する予定です。</p>」という文字列に置き換えよう。
そのためのコードは次のようになる。
|
|
HTMLPage.htmlファイルをテンプレートとして扱うコード(server.js) |
このコードは、ファイル・データにおける各プレイスホルダの文字列を、別の文字列に置換しているだけである。「/.../g」はグローバル修飾子「g」が指定された正規表現を意味し、これによって一致するものすべてが置換される。
この状態でWebアプリを実行すると、次のようになる。
![]() |
HTMLPage.htmlファイルをテンプレートとして扱う処理の実行例 |
●もっと遊ぼう。Web APIの呼び出し
筆者が何よりも大好物なのが、Tumblrである。
Tumblr! Tumblr! Tumblr!
Web APIでサンプルを作る場合、Twitter APIであることがほとんどなので、ここではあえてTumblr APIを使うサンプルを書いてみよう。今回は、筆者のTumblrから「画像」の投稿群だけを入手して、その画像に付随する各種テキストを「@@content@@」の場所に表示する。
このTumblr APIを使うには、アプリケーション登録が必要になる。これには「Tumblr Applications」のサイトを訪れ、以下の画面の手順で登録を行う。それが終わったら、[OAuth Consumer Key]をコピーする。
![]() |
[+アプリケーションを登録する]ボタンをクリック |
![]() |
![]() |
各種登録情報を入力しれ[Register]ボタンをクリックすれば登録は完了 |
![]() |
![]() |
[OAuth Consumer Key]をコピー |
HTMLPage.htmlファイルをテンプレートとして扱う処理の実行例 |
Tumblr APIの使い方はヘルプ・ページ(有志による日本語訳)に記載されている。これによると、投稿データの取得は、次のようなURLでアクセスできることが分かる。
http://api.tumblr.com/v2/blog/{base-hostname}/posts[/type]?api_key={key}&[optional-params=]
各変数部分は、今回は次のとおりに設定する。
- {base-hostname}(ブログ名): isshiki.tumblr.com
- [/type](投稿データ種別): photo
- {key}(先ほどのOAuth Consumerキー): NFenoqNUHQ82qyN4CJi19U5Clge8bMHTvO9ajrF5zKglvuzb3t
- [optional-params=](オプションのパラメータ): offset(取得開始位置)やlimit(取得するデータ数。標準は20個)などを指定できるが、今回は指定しない。
以上の内容をまとめると、
http://api.tumblr.com/v2/blog/isshiki.tumblr.com/posts/photo?api_key=NFenoqNUHQ82qyN4CJi19U5Clge8bMHTvO9ajrF5zK glvuzb3
というURLに対してGETリクエストを投げることで、JSONデータを取得すればよい。
それでは取りあえず、取得したJSONデータをそのままコンテンツとして表示してみよう。
Web APIを呼び出すには、httpモジュールのget関数が使える。
以上を踏まえて、記述したのが次のコードだ。
|
|
外部のWeb APIを呼び出すコード(server.js) |
このコードで追記/修正したのは、主に以下の内容だ。
○「http.get(...)」
get関数の第1引数には、GETリクエスト送信先の情報がオプションとして指定されている。
第2引数には、レスポンスが返ってきたときに呼び出されるコールバック関数が指定されている。
○get関数に指定されたコールバック関数
その関数の引数として、http.ClientResponseクラスのインスタンスが渡される(先ほどのhttp.ServerResponseクラスとは異なるので注意)。このオブジェクトのon関数により、dataイベントに対するコールバック関数(=「clres.on('data', function(chunk) { ... }」)と、endイベントに対するコールバック関数(=「.on('end', function() { ... }」)が定義されている。このようにイベントに対するリスナーとなるコールバック関数は、on関数で指定できる。
dataイベントでは、chunk(=ひとかたまりの部分データ)が渡されるが、あくまで一部分なので次々と足し合わせることでデータ全体を完成させる必要があり、コールバック関数ではその処理をしている。
endイベントは、全データの取得が完了したことを意味するので、このコールバック関数の中で、HTMLページの表示完了処理を行っている。
○get関数の戻り値のon関数
get関数の戻り値は、http.ClientRequestオブジェクトになる(先ほどのhttp.ServerRequestクラスとは異なるので注意)。そのオブジェクトのon関数により、errorイベントに対するコールバック関数(=「.on('error', function(e) { ... }」)が定義されている。
このコードを実行すると、次のようになる。
![]() |
外部のWeb APIを呼び出す処理の実行例 |
Tumblr APIのJSONデータがそのままテキスト表示されているのが分かる。これを適切なHTMLコードに変換しよう。
●JSONデータの変換処理
ここでは、JavaScirpt標準のJSON.parse関数を使って、JSONデータを解釈してJavaScirptのオブジェクトに変換する。オブジェクトになったデータは、次のコードのように、for文を使ったりして、内部のデータを取り出せばよい。なお、Tumblr APIの写真投稿のJSONデータ構造はマニュアルに記載されている。
|
|
JSONデータを変換する処理のコード(server.js) |
「.on('end', function() { ... }」は、前述したendイベントに対するコールバック関数である。この中で、データから写真のURLを取り出して<img>タグに変換し、そのキャプション(=HTMLコード形式)を取り出し、1つのHTMLコードにまとめ、それをWebページ上のメイン・コンテンツとして表示している。
次の画面は、本稿で作成してきたWebアプリを実行した例だ。Tumblr上の写真が、キャプションとともに20件表示される。
![]() |
JSONデータを変換する処理の実行例 |
取りあえず今回はこれで完成とする。この状態のWebアプリを気軽に試せるように、クラウド上に配置している。
●Node.js開発に欠かせないデバッガ
ここまでの説明で徐々にアプリ開発内容が複雑になってきたので、「デバッガがほしい」と思う開発者も少なくないだろう。うれしいことに、WebMatrix 2の拡張機能としてNode.jsのデバッガ(それ以外の機能も搭載されている)が無償提供されているので、最後にこれを紹介しておこう。
ちなみに先ほどのJSONデータから変換したJavaScriptのオブジェクトの構造から、データを取得する開発を筆者がした際にも、次の画面のようにしてデバッガを使った。デバッガを使えば、開発生産性を高められる。
![]() |
JSONデータから変換したJavaScriptのオブジェクトの中身をデバッガで調べている例 |
この拡張機能をWebMatrix 2に導入するには、以下の手順を参考にしてほしい。
本当はもう少しWebアプリに機能を実装したかったが、これだけの機能でも記事がかなり長くなっているので、この後の実装は後編に回す。後編では、Socket.IOへの対応や、Node.js向けWebフレームワークの「express」を勢いだけで使ってみたいと考えている。
■
以上、どんな感想を持っただろうか?
試した人は分かると思うが、WebMatrix 2+Windows Azure Webサイトを使えば、Node.js開発がとても迅速に行える。とにかく手間をかけずにNode.jsによるWeb上のサービスを無償クラウドで一般公開したいという目的なら、非常に便利である。
「コマンドラインよりもIDEを使いたい」という人なら、今回の内容は試してみる価値があるだろう。筆者はお勧めする。本稿がそのきっかけになればうれしい。
![]() |
INDEX | ||
特集:Windows開発者のためのNode.js入門 | ||
勢いで始めてみるNode.js Webアプリ開発 | ||
1.Node.jsによるWebアプリのクラウド&ローカル環境構築 | ||
![]() |
2.初めてのNode.jsによるWebアプリ開発 | |
![]() |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
![]() |
|
|
|
![]() |