https://www.nodebeginner.org/index-jp.html#javascript-and-nodejs
↑node.jsについてすごくわかりやすく書かれた入門書?です。これを元に学習!
【前回】
Node.js学んでみた ~その① 簡易サーバー作成編~
猫でもわかる〜、猿でもわかる〜、って発祥はなんなんでしょうね?
私は昔ゲームを作りたくて「猫でもわかるC言語」というサイトを16年前ぐらいに見た記憶があるので、もうその頃からはあったはずです。一行も理解できなかった猫以下の頃でした。(小学校2、3年生)
本題。
##モジュールを作ってみる
前回学んだサーバーを建てるコードを、別モジュールに写します。
var http = require('http');
function start(){
var html = require('fs').readFileSync('src/index.html')
var server = http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
process.on('uncaughtException', (e) => console.log(e));
response.end(html);
})
server.listen(8080,'127.0.0.1');
console.log("Server has started");
}
exports.start = start;
var server = require("./server");
server.start();
出したいコードをファンクション化して、export.xxx
で登録!
あとは呼び出したいファイルでrequire
すればいいですね。
ターミナルで、
node app.js
とすればhttp://localhost:8080/ にちゃんと繋がります。
##ルーティングをやる
ルーティングっていうのはHTTPリクエストに応じてコードの表示先を変えることです。これができればグッとできることが増えそうですね。
使う道具(モジュール)たち!
url
・・・URLの各部分(リクエストパスとか)を抽出するメソッドを提供
querystring
・・・リクエストパラメータのクエリ文字をパースできるメソッドを提供
HTTPリクエストをこれらを使ってやっつけます。
var http = require('http');
var url = require('url'); //urlモジュール追加
function start(){
var html = require('fs').readFileSync('src/index.html')
var server = http.createServer(function(request,response){
var pathname = url.parse(request.url).pathname;
console.log("Request for" + pathname + " received."); //パス表示
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
process.on('uncaughtException', (e) => console.log(e));
response.end(html);
})
server.listen(8080,'127.0.0.1');
console.log("Server has started");
}
exports.start = start;
url部分をパチパチ打ち込んで変えてみると、ちゃんとターミナルにそれが表示されるのがわかるかと思います。
これを使えばルーティングできますね。
このままでは管理しずらいのでサーバーとルーターの機能を分けます。
function route(pathname) {
console.log("About to route a request for " + pathname);
}
exports.route = route;
パス表示部分のファイルですね。
var http = require('http');
var url = require('url');
function start(route){
var html = require('fs').readFileSync('src/index.html')
var server = http.createServer(function(request,response){
var pathname = url.parse(request.url).pathname;
route(pathname); //ルーティング部分
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
process.on('uncaughtException', (e) => console.log(e));
response.end(html);
})
server.listen(8080,'127.0.0.1');
console.log("Server has started");
}
exports.start = start;
サーバー部分の処理になります。routeを呼び出していますね。
var server = require("./server");
var router = require("./router");
server.start(router.route);
2つのモジュールを呼び出して、関数を読み込んで実行します。
これで機能別にモジュール化できたので、あとはルーティングの肝部分です!
リクエストハンドラーは増減が激しいのでオブジェクトとして登録します。
まずはrequestHanders.jsというファイルを以下のように作ります。
function start(){
console.log("startが呼ばれました");
}
function upload(){
console.log("uploadが呼ばれました");
}
exports.start = start;
exports.upload = upload;
お次にこれらをapp.jsで呼び出して、オブジェクトとして登録。
startに関しては、/
でもルーティングできるようになっていますね。
オブジェクトをsever.startに第二引数として渡しています。
var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers"); //呼び出し
var handle = {} //オブジェクト化
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
server.start(router.route,handle);
次はappから呼び出されているserver.jsを修正します。
function start
の第二引数handle
を増やしてあげて、
route
関数呼び出し時の第一引数にそのままhandle
を入れています。
var http = require('http');
var url = require('url');
function start(route,handle){
var html = require('fs').readFileSync('src/index.html')
var server = http.createServer(function(request,response){
var pathname = url.parse(request.url).pathname;
console.log("Request for" + pathname + " received.");
route(handle,pathname);
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
process.on('uncaughtException', (e) => console.log(e));
response.end(html);
})
server.listen(8080,'127.0.0.1');
console.log("Server has started");
}
exports.start = start;
最後にrouter.js
の修正です。
function route(handle,pathname){
console.log("About to route a request for " + pathname);
if(typeof handle[pathname]==='function'){
handle[pathname]();
}else{
console.log("No request handler found for" + pathname);
}
}
exports.route = route;
handle[pathname]
がfunctionである時、つまり存在する時は
handle[pathname]();
、つまりrequestHandlers.jsの関数たちが実行されます。
functionでない時、つまり存在しない時はエラーメッセージをconsole.log
で出してあげていますね。
モジュールをたくさん分離していますが、おかげで各機能が明白でいい感じです。
Server has started
Request for/ received.
About to route a request for /
startが呼ばれました
http://localhost:8080/ にアクセスすると上記のようになります。
Request for/upload received.
About to route a request for /upload
uploadが呼ばれました
http://localhost:8080/upload にアクセスすると上記のようになります。
ルーティング成功です!
(※faviconに関するメッセージは省略しています)