14
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Node.js学んでみた ~その② ルーティング編~

Posted at

https://www.nodebeginner.org/index-jp.html#javascript-and-nodejs
↑node.jsについてすごくわかりやすく書かれた入門書?です。これを元に学習!

【前回】
Node.js学んでみた ~その① 簡易サーバー作成編~

猫でもわかる〜、猿でもわかる〜、って発祥はなんなんでしょうね?
私は昔ゲームを作りたくて「猫でもわかるC言語」というサイトを16年前ぐらいに見た記憶があるので、もうその頃からはあったはずです。一行も理解できなかった猫以下の頃でした。(小学校2、3年生)

本題。

##モジュールを作ってみる
前回学んだサーバーを建てるコードを、別モジュールに写します。

server.js
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;
app.js
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部分をパチパチ打ち込んで変えてみると、ちゃんとターミナルにそれが表示されるのがわかるかと思います。
これを使えばルーティングできますね。

このままでは管理しずらいのでサーバーとルーターの機能を分けます。

router.js
function route(pathname) {
  console.log("About to route a request for " + pathname);
}

exports.route = route;

パス表示部分のファイルですね。

app.js
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を呼び出していますね。

app.js
var server = require("./server");
var router = require("./router");
server.start(router.route);

2つのモジュールを呼び出して、関数を読み込んで実行します。

これで機能別にモジュール化できたので、あとはルーティングの肝部分です!
リクエストハンドラーは増減が激しいのでオブジェクトとして登録します。
まずはrequestHanders.jsというファイルを以下のように作ります。

requestHanders.js
function start(){
  console.log("startが呼ばれました");
}

function upload(){
  console.log("uploadが呼ばれました");
}

exports.start = start;
exports.upload = upload;

お次にこれらをapp.jsで呼び出して、オブジェクトとして登録。
startに関しては、/でもルーティングできるようになっていますね。
オブジェクトをsever.startに第二引数として渡しています。

app.js
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を入れています。

server.js
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の修正です。

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に関するメッセージは省略しています)

14
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?