こんにちは、のすけです。

JavaScriptでサーバサイドとか面倒そう!ということで今まで敬遠していたのですが
実は手軽に利用出来るようです。

面倒そうと考えた理由としては、JavaScriptはクライアントサイドが普通ですので、何でわざわざJavascriptでサーバサイドまで作らにゃいけないのさ!

もっとWebで使いやすい専用言語とかFrameworkとかあるじゃん!

と思っていたのですが、、、書籍をサラッと見た感じだと、どうやらシンプルなHTTP通信ならnodeいいんじゃね?
という認識に変わりました。

f:id:hollywis:20151226225042p:plain

僕はサーバサイドは今までサーブレッット(Java)や.NetFramework(C#)、Rails(Ruby)を使ってきました。
最近はWebでのライブラリの豊富さからRailsばかり触っていましたが、ついにNodeを使ってみることにしました。

なお下記の書籍を購入してしまったので、これを参考に実装しながら学習していこうかと思います。

Nodeクックブック

Nodeクックブック

Nodeの特徴

NodeはどうやらWebサーバとアプリケーションサーバが分離していないようです。
また、Webサーバ機能はプログラミングで作ってしまうことができるため、極めて手軽にWebを始めることができるとのこと。

プログラミング言語JavaScriptです。
クライアントサイドのプログラミング言語として最近は使われまくっているので、言語の敷居は低いですね。

パッケージ管理システムとしてRailsでしたらbundlerがありますが、Nodeではnpmというものがあるようです。安心ですね。

また、個々のリクエストは非同期で処理されI/Oをブロックしません。そのため、多くの同時接続を処理することができます。
シングルスレッドであるため、リクエスト毎にプロセスを生成&メモリ割当をするということもないようです。

実はNodeを使おうとした理由としてチャットシステムを作ろうとしたというのがあります。
従来のサーバサイドプログラムと比較して、同時接続という部分では一番パフォーマンスが良いのではないかと勝手に期待しています。

環境

Macにあらかじめ入れていたNodeを利用していきます。いつ入れたんだろう?

$ node -v
v5.0.0
$ npm -v
3.3.9
$node -p process.versions.v8
4.6.85.28

nodeを起動

有名なFrameworkとしてexpress.jsというのがあるようですが、Nodeを基本から理解するためフレームワークなしでnodeに触れてみたいと思います。
どうやらNodeではかなりシンプルにWeb機能が実装できるようですので。

server.jsというファイルを作る

一般的にサーバ生成用のファイル名はserver.jsという名前にする慣例があるようです。

中身に次のように書きます。

var http = require('http');
var PORT = 8080;
http.createServer(function (request,response){
response.writeHead(200,{'Content-Type':'text/html'});
response.end('HelloWorld!\n')
}).listen(8080);
console.log('Server running at http://localhost'  + ':' + PORT + '/');

httpというモジュールをrequireして、createServerでサーバ起動しています。
これだけのようです。シンプルすぎる。。。

ヘッダーにHTTPヘッダーとして、ステータスコード200、Contet-Type text/htmlを設定します。
htmlのbodyとしてHelloWorldを入れています。

なおHTTPについての知識が曖昧な場合には、こちらの書籍がオススメです。
そもそも、HTTPやHTMLとは何なのかが分かりやすく記載されています。
僕も分かっていたつもりでしたが、知らないことも多く読んでかなり頭の中がスッキリしました。

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

hotnodeをインストール
$ npm -g install hotnode
hotnodeでnodeを起動

server.jsというファイルがある場所に移動して、下記でnodeを起動します。

$  hotnode server.js

なお、通常は次のように起動します。hotnodeの利点は、実行ファイルの変更を検知すると再起動して読み直してくれます。
そのため、hotnodeで起動した方が良いでしょう。

$  node server.js

この状態で localhost:8080にアクセスすると「HelloWorld!」と表示されました。

超シンプルだ。

URLルーティングの作成

このままだと localhost:8080/fooも localhost:8080/varも全て「HelloWorld!」になるため
アクセスしてくるURLのパスを見て、適切な場所にルーティングし表示を変えてみます。

var http = require('http');
var PORT = 8080;
var path = require('path');  // 追加
http.createServer(function (request,response){
var lookup = path.basename(decodeURI(request.url));  // 追加
//・・・

pathモジュールをrequireしています。
request.urlからurlパスを取得しdecodeURIでデコードします。
basenameはパスの最後の部分を取り出します。

ルーティングを記載

ルーティングは配列pagesで定義してみます。
forEachでpages配列を参照して、lookpupとマッチする場合に該当のoutputを出力します。

//・・・
var pages = [
{route:'',output:'HelloWorld!\n'},
{route:'foo',output:'fooのページです\n'},
{route:'var',output:'varのページです\n'},
{route:'another page',output: function(){ return 'これが'+this.route+'ページです\n'}}
];
http.createServer(function (request,response){
var lookup = path.basename(decodeURI(request.url));
pages.forEach(function(page){
if(page.route === lookup){
response.writeHead(200,{'Content-Type':'text/html'});
response.end(typeof page.output === 'function' ? page.output() :page.output);
}
});
if(!response.finished){
response.writeHead(404);
response.end('ページが見つかりません!');
}
}).listen(8080);
//・・

これで以下でそれぞれ違う出力が出ました。
なお、ブラウザのエンコードUTF-8にしないと文字化けます。

まとめ

nodeはかなりシンプルにwebサーバを作ることができました。
ルーティング機能すらプログラミングで作ってしまえるなど、自由度が高いのが素晴らしいです。

簡易的なHTTP通信が必要なIoT系の通信なんかはサラッと実装できそうですね。

毛嫌いしていましたが、なかなか有用な技術だと思いました。
とりあえず、nodeでチャット作成を目指して勉強していこうと思います。