Express.js 기초
교내 웹개발 동아리 Kweb 스터디에서 배운 내용을 정리하였다. 스터디에서 사용한 강의 자료를 참고하였다.
개요
Express.js
는 JavaScript
및 Node.js
기반 웹 프레임워크의 일종이다.
웹 프레임워크에는 웹 서버에 필요한 기본적인 기능들이 미리 갖춰진 채로 제공되고 있어, 개발자는 이를 활용하여 웹 서비스를 빠르게 구현할 수 있다.
설치
다음 명령어로 Node.js
프로젝트 폴더에 Express.js
를 설치할 수 있다.
npm install express
기본 사용법
const express = require('express'); // express 모듈을 가져온다.
const app = express(); // express 객체를 생성한다.
const port = 3000; // 서버 포트를 설정한다.
app.get('/', (req, res) => res.send('Hello World!'));
// app.get() 메소드를 통해 / 라우트로 들어온 요청에 응답(response)을 보낸다.
// 요청 객체 req에는 http 요청에 대한 정보가 들어있고, 응답 객체 res에는 응답에 대한 정보가 들어있다.
app.listen(port, () => console.log(`Server listening on port ${port}!`));
// app.listen() 메소드를 통해 지정된 포트로 서버를 개방하여 클라이언트의 요청을 listening한다.
get()
과 같은 라우팅 메소드는 첫 번째 argument로 라우팅 경로를 받고, 두 번째 argument로는 해당 라우팅 경로에서 실행할 함수, 즉 controller 함수를 받는다.
‘라우트(route)’는 HTTP 요청 메소드와 경로(path)를 묶어서 일컫는 말이다. 예를 들면
GET /
는 하나의 라우트라고 볼 수 있다.
- 응답 객체(
res
)가 사용 가능한 메서드.send
: 문자열 또는html
문서를 클라이언트에게 보낸다..status
: 응답 상태 코드를 설정한다..redirect
: 클라이언트를 다른 경로로 리다이렉트한다.
- 요청 객체 (
req
) 필드
Middleware
미들웨어(Middleware) 란, 요청과 응답의 중간에 위치하여 두 객체 사이의 동작을 제어하는 함수를 말한다.
app.use((req, res, next) => {
const randomNumber = Math.floor(Math.random() * 10);
console.log(`Random Number: ${randomNumber}`);
if (randomNumber % 3) return next();
else return res.sendStatus(403);
});
app.use((req, res, next) => {
const { method, path } = req;
console.log(`${method} ${path}`);
return next();
});
// app.use() 메소드를 통해 미들웨어를 등록(bind)할 수 있다.
-
use()
메소드 사용법use()
메소드에는 두 개의 argument가 있는데, 첫 번째 argument는 미들웨어가 적용될 경로를 지정하고, 두 번째 argument는 미들웨어 함수를 지정한다.이때 argument가 하나만 전달되는 경우에는 첫 번째 argument가 생략된 것으로 취급되어 지정된 미들웨어 함수가 모든 경로에 대해 실행된다.
미들웨어는 다음과 같은 특징이 있다.
- 미들웨어는
use()
메소드를 통해 bind된 순서대로 실행된다. - 미들웨어 역시
req
,res
객체에 접근할 수 있다. - 미들웨어에서
next()
함수를 호출하면 다음 미들웨어가 실행되며, 응답 객체res
를 이용하여 응답을 보내면 이후의 미들웨어는 실행되지 않는다.
위와 같은 특징, 특히 미들웨어의 순차적 실행이라는 Express.js
의 특성으로 인해 미들웨어는 Express.js
애플리케이션에서 중요한 역할을 한다.
req
와 같은 요청 객체에 대한 전처리, 로깅, 에러 처리, 라우팅 등은 모두 미들웨어의 형태로 작성 가능하다.
미들웨어를 활용한 라우팅
const { Router } = require('express');
const router = Router();
router.get('/', (req, res) => res.send('GET /'));
router.post('/', (req, res) => res.send('POST /'));
module.exports = router;
router.js
const express = require('express');
const router = require('./router');
const port = 3000;
const app = express();
app.use('/', router);
app.listen(port, () => console.log(`Server listening on port ${port}!`));
index.js
이 프로그램을 라우팅 기능을 미들웨어 형태로 router.js
에 구현하고, index.js
에서 router.js
를 불러와 사용한다. 위와 같이 미들웨어를 활용하면 라우팅 기능과 관련된 코드를 분리하여 프로젝트를 구조화할 수 있다.
위와 같이 use()
메소드를 이용하여 라우팅 경로를 지정하면 router.js
에서 지정한 라우팅 경로는 use()
메소드에서 지정된 경로에 대한 하위 경로로 인식된다.
예를 들어 index.js
에서 아래와 같이 코드를 작성하고,
app.use('/api', router);
index.js
router.js
에서 아래와 같이 코드를 작성하면,
router.get('/post', (req, res) => res.send('GET /post'));
router.js
GET /api/post
에 대한 요청이 들어왔을 때 router.js
에서 정의한 send()
함수가 실행된다.
ViewEngine
Express.js
는 ViewEngine
을 지원한다. ViewEngine
을 사용하면 HTML
파일을 간편하게 렌더링하여 클라이언트에게 전달할 수 있다.
대표적인 ViewEngine
으로는 pug
, ejs
, jinja2
가 있다. 이 글에서는 pug
를 사용한다.
pug 설치
npm install pug
pug 사용
app.set('views', `${__dirname}/views`);
//프로젝트 폴더 하위의 views 폴더를 ViewEngine이 사용할 템플릿 폴더로 지정
app.set('view engine', 'pug');
//ViewEngine을 pug로 지정
app.get('/', (req, res) => res.render('index.pug'));
//템플릿 파일을 HTML 파일로 렌더링하여 응답으로 전송
views
폴더에 index.pug
파일을 생성하고 pug
문법에 맞게 템플릿을 작성하면, pug
가 HTML
로 변환하여 클라이언트에게 전달한다.
pug
문법에 대해서는 이 게시글에서 자세하게 다루지 않을 것이다.
pug
의 자세한 문법은 공식 문서를 참고하자.
-
GET
요청일 때 주로 사용된다. ↩ -
참조: Semantic URL ↩
-
POST
요청일 때 주로 사용된다. ↩