Node.js의 파일 서버 방식의 웹 서버 운용은 보안이 너무 취약하며, 그렇다고 라우팅, 세션 관리 등을 직접 코딩하는 것은 사실상 번거로운 면이 많이 있다.
이에 Node.js는 Web Framework를 지원한다. 대표적인 Web Framework로는 “Express”, “Koa”, “Hapi” 등이 있는데, 우리는 그 중 가장 잘 나가는 친구인 “Express”에 대해 배워 보려 한다.
“Node.js를 위한 빠르고, 명료하고, 컴팩트한 웹 프레임워크”라고 한다…
Express 디렉토리 구조
일반적인 Express 디렉토리의 구조는 아래와 같다.
express_tutorial/
├── package.json
├── public
│ └── css
│ └── style.css
├── router
│ └── main.js
├── server.js(app.js)
└── views
├── about.html
└── index.html
이제부터는 프로젝트 단위로 진행되기 때문에 별도의 루트 디렉토리를 만들어서 관리를 하는 것이 좋다.
package.json
express_tutorial 디렉토리를 만들고, 해당 디렉토리 루트에 아래와 같은 정보로 package.json 을 작성한다.
package.json
{
"name": "express-tutorial",
"version": "1.0.0",
"dependencies": {
"express": "~4.13.1",
"ejs": "~2.4.1"
}
}
package.json 은 메이븐(Maven)의 pom.xml 같은 역할을 한다. 이는 모듈의 디펜던시와 버전 관리에 대한 정보를 담아두고 있는 json 파일이며, 이 정보를 추가/수정 하는 것으로 손 쉽게 프로젝트 내의 모듈들을 관리 할 수 있다.
package.json 의 작성이 완료되었다면, 이를 적용시켜 패키지들을 다운로드 해 보자.
npm install
npm install 뒤에 아무 패키지명도 붙지 않는다면, 작업 디렉토리 내의 package.json 을 검색하여, 디펜던시에 해당하는 모듈들을 자동으로 다운로드 한다. 위의 예제의 경우에는 express 모듈과, ejs 모듈이 다운로드 될 것이다.
package.json 을 따로 건드리고 싶지 않다면..
새로운 프로젝트를 시작할 때 마다, package.json 을 건드는 것은 썩 유쾌한 일은 아닐 것이다. 또한, 자주 사용되는 모듈에 대해서 프로젝트가 바뀔 때마다 다시 적는것도 좋은 일은 아니다.
모듈 설치와 동시에 package.json 에 디펜던시로 등록되게 하는 명령어가 있다.
npm install [모듈명] --save
–save 옵션으로 모듈을 설치한다면, 해당 프로젝트에 모듈이 설치됨과 동시에 package.json 에 해당 모듈에 대한 디펜던시가 자동으로 등록된다.
새로운 프로젝트를 진행할 때는, 기반이 되는 프로젝트의 package.json 파일을 복사해서 npm install 명령어 만으로 간단하게 모듈 설치가 가능할 것이다.
Express 서버 생성하기
이제 express 모듈을 사용해서 서버를 생성해 볼 것이다. 디렉토리 루트에 server.js 를 작성해 보자
server.js
// Express 서버
var express = require('express');
var app = express();
var server = app.listen(80, function(){
console.log("Express server has started on port 80")
});
express 모듈을 추가하고, app에 express 객체를 담아서, app 객체를 통해 express Framework를 활용하게 된다. 4번행 부터 웹 서버를 80 포트를 Listen 받아 열게 되는데, 아무런 response 를 설정하지 않았기에, 현재는 접속을 해도 “Cannot Get /” 과 같은 204 No Content 결과를 얻게 된다.
라우터
유저에게 request 를 받아서 response 를 하기 위해서는 라우터 라는 개념이 필요하다. (물리적 통신장치인 “그” 라우터 와는 다르다) 위에서 작성헀던 server.js 아래에 해당 소스 코드를 추가하자.
server.js
// 라우터
app.get('/', function(req, res){
res.send('Hello World');
});
다시 서버를 실행하고, 접속하면 다음과 같은 결과를 확인할 수 있다.
서버와 라우터의 분리
그러나, 서버 코드와 라우터 코드는 별도의 파일로 작성해서 관리하는 것이 표준 코딩 방식이다. 위의 express 디렉토리 구조에서 볼 수 있듯이, router 디렉토리를 생성해서 라우터 코드를 관리할 main.js 를 작성하자.
/router/main.js
module.exports = function(app) // 외부 접근용 메소드
{
app.get('/',function(req,res){ // 루트(/) 접근
res.render('index.html')
});
app.get('/about',function(req,res){ // /about 접근
res.render('about.html');
});
}
그리고, 라우터 코드인 main.js 를 서버 코드인 server.js 에서 include 하고 설정을 조금 바꿔줘야 한다. 아래의 소스 코드대로 server.js 를 수정하자
server.js
var express = require('express');
var app = express();
var router = require('./router/main')(app); // 라우터 코드
app.set('views', __dirname + '/views'); // HTML 문서 위치 지정
//HTML 렌더링에 ejs 모듈을 사용함:
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
//3000포트로 웹 서버를 생성:
var server = app.listen(3000, function(){
console.log("Express server has started on port 3000")
});
뷰(View, HTML 페이지) 띄우기
server.js 의 설정에 따라 모든 뷰(View) 들은 /views 디렉토리에서 로드된다. 그렇다면 /views 디렉토리를 생성하고 main.js 에서 정의한 index.html과 about.html 을 간단하게 만들자.
정적 파일(Static files) 추가하기
정적 파일(css, js, img)을 사용하기 위해서는 express.static() 메소드를 사용하면 된다. public/css/ 디렉토리를 생성 후, style.css 를 생성하자.
/public/css/style.css
body{
background-color:black;
color:white;
}
/views/index.html (about.html)
<link rel="stylesheet" type="text/css" href="css/style.css">
이제 해야 할 일은 정적 파일의 기본 디렉토리를 server.js 에서 설정하는 것만 남았다. server.js 에서 정적 파일 기본 디렉토리를 /public 으로 설정하자
server.js
app.use(express.static('public')); // 정적 파일 경로 추가