http 요청이 다른 코드를 가리키는 것을 라우팅이라 한다.
그것을 위해서는 먼저 http요청의 url과 get/post 부분을 뽑아내야 한다.
이것을 위해 node에서는 url 모듈을 지원한다. 또한 querystring은 query string을 request 파라미터로 파싱하는데 사용한다.
이런 요청이 있다고 하자.
http://localhost:8888/start?foo=bar&hello=world
그리고 요청이 들어왔을 때 콘솔에 출력할 코드를 작성한다.
server.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | var http = require("http"); var url = require("url"); var querystring = require("querystring"); function start(){ http.createServer(function(request, response){ console.log("Request received."); var u = request.url; var query = url.parse(u).query; var pathname = url.parse(u).pathname; var foo = querystring.parse(u)["foo"]; var hello = querystring.parse(u)["hello"]; console.log("query : " + query + "\n" + "pathname : " + pathname + "\n" + "foo : " + foo + "\n" + "hello : " + hello); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); }).listen(8888); console.log("Server has started"); end(); } function end(){ console.log("call end"); } exports.start = start; | cs |
그리고 위의 주소로 요청하면,
C:\Users\Administrator\data_node>node index.js
Server has started
call end
Request received.
query : foo=bar&hello=world
pathname : /start
foo : undefined
hello : world
왜인지 foo의 값이 undefined가 된다... 왜일까?
start? 뒤에 &를 추가한뒤 해보았다.
C:\Users\Administrator\data_node>node index.js
Server has started
call end
Request received.
query : &foo=bar&hello=world
pathname : /start
foo : bar
hello : world
잘 출력된다. 즉, querystring의 문법에 조금 문제가 있다는 것을 알 수 있다. 이유는 아직 모르겠다. 구글링을 해도 나오지 않는다...
이제 진짜 라우터를 작성해본다.
route.js
1 2 3 4 5 | function route(pathname){ console.log("About to route a request for " + pathname); } exports.route = route; | cs |
새로운 파일을 만들고 모듈화 한다.
server.js를 확장한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | var http = require("http"); var url = require("url"); var querystring = require("querystring"); function start(route){ http.createServer(function(request, response){ console.log("Request received."); var pathname = request.url.pathname; route(pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); }).listen(8888); console.log("Server has started"); end(); } function end(){ console.log("call end"); } exports.start = start; | cs |
index.js를 확장하고 주입-inject- 한다.
1 2 3 4 | var start = require("./server"); var router = require("./route"); start.start(router.route); | cs |
그리고 요청을 보내면,
1 2 3 4 5 | C:\Users\Administrator\data_node>node index.js Server has started call end Request received. About to route a request for /start | cs |
현재 router.js가 하는 일은 콘솔에 출력하는 것 밖에 없지만, 이 것을 기초로 라우팅을 한다.
실제 라우팅을 하기 위해, requestHandler를 작성한다. 이를 위해 requestHandlers.js를 생성하고 파일을 작성한다.
requestHandlers.js
1 2 3 4 5 6 7 8 9 10 | function start() { console.log("Request handler 'start' was called"); } function upload(){ console.log("Request handler 'upload' was called"); } exports.start = start; exports.upload = upload; | cs |
index.js
1 2 3 4 5 6 7 8 9 10 11 | var server = require("./server"); var router = require("./route"); var requestHandlers = require("./requestHandlers"); var handle = {} handle["/"] = requestHandlers.start; handle["/start"] = requestHandlers.start; handle["/upload"] = requestHandlers.upload; console.log(handle); server.start(router.route, handle); | cs |
server.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var http = require("http"); var url = require("url"); var querystring = require("querystring"); function start(route, handle){ http.createServer(function(request, response){ console.log("Request received."); var pathname = url.parse(request.url).pathname; route(handle, pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); }).listen(8888); console.log("Server has started"); } exports.start = start; | cs |
route.js
1 2 3 4 5 6 7 8 9 10 11 | 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; | cs |
index.js에 명시한 handle을 통해 요청 주소값에 따라 다른 분기를 타도록 설정한다. 그리고 route에서 handle[pathname](); 구문으로 해당 함수를 실행한다.
실행결과
1 2 3 4 5 6 | C:\Users\Administrator\data_node>node index.js [Function: start] Server has started Request received. About to route a request for / Request handler 'start' was called | cs |
댓글