728x90

 

http.createServer(async (req, res) => {
  try {
    if (req.method === 'GET') {
      if (req.url === '/') {
        const data = await fs.readFile(path.join(__dirname, 'restFront.html'));
        res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
        return res.end(data);
      } else if (req.url === '/about') {
        const data = await fs.readFile(path.join(__dirname, 'about.html'));
        res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
        return res.end(data);
      } else if (req.url === '/users') {
        res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
        return res.end(JSON.stringify(users));
      }

 
위 코드는 http모듈의 웹 브라우저의 요청을 처리할 수 있는 createServer() 메서드입니다.
 
request를 줄여 reqresponse을 줄여 res로 표현하는데 req 객체는 요청에 관한 정보들을, res 객체는 응답에 대한 정보들을 담고 있습니다.
 
req.methodHTTP 요청 메서드를 구분하고 있으며, 요청에 따라서 res로 응답의 헤더와 본문을 하는 간단한 createServer() 메서드입니다.
 
그러나 위와 같이 간단한 요청을 처리하는 메서드가 아니라 규모가 커지면 커질수록 코드는 복잡해지며 가독성과 확장성이 떨어진다고 느낄 수 있습니다.
 
node.js는 이때 사용할 수 있는 편의 기능을 제공하는데 바로 이번 포스팅에서 알아볼 express입니다.
 

express 익스프레스란❓

npm i express
	or
npm install -D express

 
Express는 웹 및 모바일 애플리케이션을 위한 일련의 강력한 기능을 제공하는 간결하고 유연한 node.js 웹 애플리케이션 프레임워크입니다.
 
경량화 웹 개발 프레임 워크라고 할 수 있으며 웹 서비스나 웹 애플리케이션 개발에 가장 많이 쓰이는 확장 모듈 중 하나입니다.
 

https://npmtrends.com/

 
express 외에도 koa나 hapi 등 웹 서버 프레임워크가 있지만 위 그림을 보면 알 수 있듯이 다운로드 수의 차이가 어마어마합니다.
 
인기가 많은 만큼 버그가 적고, 기능 추가유지 보수도 활발하게 이루어져 있어 express의 인기는 꾸준히 상향하고 있습니다.
 

 
express를 설치하고 나면 package.json파일을 보면 의존성(dependencies)에 express가 추가된 것을 볼 수 있습니다.
 

const express = require('express');
const path = require('path');

const app = express();

app.set('port', process.env.PORT || 3000);


app.get('/', (req, res) => { 
  res.sendFile(path.join(__dirname, '/index.html'));
});

app.get('/about', (req, res) => {
  ...
}

app.post('/', (req, res) => {
  ...
}

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '번 포트에서 대기 중');
});

 
위 코드를 보면 앞선 process.env 포스팅에서 알아보았던 시스템 환경변수인. env의 PORT나 직접 3000으로 지정합니다.
 
맨 위에서 말했던 req.method로 HTTP 메서드와 같이 요청에 따라 동작을 분기처리하여 지정해 주는 것과 다르게 express를 사용하면 위 코드와 같이 간결하게 만들 수 있습니다.
 

미들웨어 middleware란❓

 

미들웨어 middleware는 익스프레스 express의 핵심👌

 
위 그림을 보면 알 수 있듯이 요청(Request)과 응답(Response)중간(middle)에 위치하여 미들웨어라고 불립니다.
 
추후에 포스팅을 할 라우터(Router)에러 핸들러 역시 middleware의 일종이므로 middleware가 express의 전부라고 해도 과언이 아닙니다.
 
간단히 말해 미들웨어함수는 요청(req)과 응답(res) 중간에 위치하며 클라이언트에게 요청이 오면 해당 요청에 대한 응답을 중간에서 적절하게 보내기 위해 목적에 맞게 처리해 주는 함수라고 할 수 있습니다.
 

app.use(미들웨어)

 
middleware는 위와 같이 app.use와 함께 사용됩니다.

app.get('/', (req, res, next) => { 
  console.log("GET / 요청에서만 실행");
  res.sendFile(path.join(__dirname, '/index.html'));
  next(); // 다음 미들웨어 함수를 실행
});

 
function(req, res, next) {} 부분이 바로 미들웨어입니다. express 서버에 미들웨어를 연결하려면 app.use에 매개변수가 req, res, next인 함수를 넣으면 됩니다.
 
그리고 중요한 점은 각각의 미들웨어에서는 next() 메서드를 호출해야지 그다음 미들웨어가 작업을 처리할 수 있도록 순서를 넘길 수 있습니다.
 
위 코드를 보면 app.get 라우터에 미들웨어가 두 개 연결되어 있는데 이때도 next()를 호출해야지 다음 미들웨어로 넘어갈 수 있습니다.
 

app.get()의 첫 번째 인수주소를 넣어주지 않는다면 모든 요청에서 실행되고, 주소를 넣는다면 해당 주소에서만 실행이 됩니다.

 

var express = require('express');

var app = express();

app.use(function (req, res, next) {
  req.requestTime = Date.now();
  next();
});

app.get('/', function (req, res) {
  res.send(req.requestTime);
});

app.listen(3000);

 
위 코드에서 첫 번째 미들웨어에서 Date.now()로 requestTime 객체에 시간을 지정해 주고, next()로 다음 미들웨어에게 순서를 넘겨주었기 때문에 두 번째 미들웨어에서 requestTime객체를 호출하여 데이터를 사용할 수 있습니다.
 
만약 next()를 사용하지 않았으면 두 번째 미들웨어에서 데이터를 사용할 수 없습니다.
 

에러 처리 미들웨어

...

app.get('/error', (req, res, next) => {
    next();
}, (req, res) => { 
	try {
    	// .. error 발생 코드
    } catch(err) {
    	error(err);
    }  
});

...

app.use((err, req, res, next) => { 
    console.error(err);
    res
    	.status(500)
        .send(err.message); 
})

 
app.get의 두 번째 미들웨어에서 error를 발생시키는 코드를 try {}에서 작성했다고 가정한다면 catch {}에서 error가 잡히게 될 것입니다.

그런데 이때 next(error)처럼 next() 함수 인자로 error를 주게 된다면 기본적인 middleware 패턴에서 해당 에러 객체를 가진 함수로 바로 넘어갈 수 있습니다.
 
에러 처리 미들웨어는 매개변수가 (err, req, res, next)로 4개입니다. 또한 에러 처리 미들웨어는 가장 아래에 위치하는게 좋습니다.

  • err : 에러에 관한 정보가 담겨져있습니다.


 

오류 처리 미들웨어의 인수는 (err, req, res, next) 무조건 4개입니다.

모든 매개변수를 사용하지 않더라도 반드시 4개여야 되며, 하나라도 생략된다면 "일반 미들웨어"로 간주됩니다.

next() 또한 마찬가지로 4개

 

 

Reference