/ PROGRAMMING, WEB, BACKEND, JS

Express.js 기초

교내 웹개발 동아리 Kweb 스터디에서 배운 내용을 정리하였다. 스터디에서 사용한 강의 자료를 참고하였다.

개요

Express.jsJavaScriptNode.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) 필드
    • .query : HTTP request query1
    • .params : HTTP request parameters2
    • .body : HTTP request body3

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가 생략된 것으로 취급되어 지정된 미들웨어 함수가 모든 경로에 대해 실행된다.

미들웨어는 다음과 같은 특징이 있다.

  1. 미들웨어는 use() 메소드를 통해 bind된 순서대로 실행된다.
  2. 미들웨어 역시 req, res 객체에 접근할 수 있다.
  3. 미들웨어에서 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.jsViewEngine 을 지원한다. 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 문법에 맞게 템플릿을 작성하면, pugHTML로 변환하여 클라이언트에게 전달한다.

pug 문법에 대해서는 이 게시글에서 자세하게 다루지 않을 것이다. pug의 자세한 문법은 공식 문서를 참고하자.

  1. GET 요청일 때 주로 사용된다. 

  2. 참조: Semantic URL 

  3. POST 요청일 때 주로 사용된다.