Express와 미들웨어

프최's log·2020년 9월 29일
1

study

목록 보기
22/59
post-thumbnail

웹 프레임워크 : Express

 JavaScript 생태계에서 인기 있는 프레임워크의 앞글자를 따서 MERN stack (MongoDB, Express, React, Node) 로 부른다. 이 중 Express.js는 Node.js 를 위한 빠르고 개방적인 간결한 웹 프레임워크 중 하나로, 라우팅/세션과리 등 골치아픈 부분을 해결하여 쉽게 웹 서버를 구축할 수 있게 도와준다.

express 설치

// packages.json 파일 내 dependencies 목록에 추가
$ npm install express --save

express 서버 생성

Hello world 예제는 공식문서를 참조하여 가장 간단하게 만들어볼 수 있는 서버이다.
※ 하단 코드는 npm init 와 express가 설치가 완료된 것을 전제한 코드이다. 세팅 참조

//server.js
const express = require('express')
const app = express()
const port = 3000
//Router로 Request 처리
app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

라우팅 : 메소드 및 URL 분기

 라우터 코드와 서버코드는 다른 파일에 작성하는 것은 좋은 코딩 습관이라고 한다. 위 코드와 연결되는 router.js 는 아래와 같이 만들어질 수 있다.

module.exports = function(app)
{
     app.get('/messages',function(req,res){
        //...do something..
     });
     app.post('/messages',function(req,res){
        //...do something..
     });
}

그리고 server.js 에서 라우터 모듈을 불러와서 app에 전달해줘야한다.

//server.js
const express = require('express');
const app = express();
const router = require('./router.js');
const port = 3000

app.use("/", routes);

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

미들웨어(Middleware)란 무엇인가

컨베이어 벨트 위에 올라가있는 request에 무언가 악세사리를 붙이거나, 불량품이라면 밖으로 걷어내는 역할을 한다. 미들웨어는 express의 큰 장점 중 하나다. express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출이다.

express 미들웨어 사용

미들웨어가 주로 쓰이는 상황

  1. 모든 요청에 대해 url이나 메소드를 알고자 할 때
  2. POST 요청 등에서 쓰이는 body(payload)를 쉽게 얻어내고자 할 때
  3. 모든 요청/응답에 CORS 헤더를 붙일 때
  4. 요청 헤더에 사용자 인증 정보가 담겨있는지 확인하고 싶을 때

node.js를 이용해 구현할 때마다 번거로운 작업을, 보다 손쉽게 해결해주는 역할을 한다.

2,3번은 express에서 흔히 사용되는 써드파티 미들웨어이다.

case 2 : body-parser 미들웨어

순수 node.js 코드를 이용할 때 HTTP body(payload)를 받아내기 위해서는 Buffer를 조합해 다소 복잡한 방식으로 body를 얻어내야하지만, 이를 쉽게 바꿔주는 역할을 하는 것이 body-parser 미들웨어 이다.

const bodyParser = require('body-parser')
const jsonParser = bodyParser.json()

// 생략
app.post('/api/users', jsonParser, function (req, res) {
  // req.body에는 JSON의 형태로 payload가 담겨져 있습니다.
})

case 3: cors 미들웨어

순수 node.js 코드로 CORS 헤더를 붙이기 위해서는 writeHead 메소드 등을 이용하여 Access-Control-Allow-* 헤더를 정의해줘야 했다. OPTIONS 메소드에 대한 라우팅도 구현해줘야 했지만 이를 쉽게 해주는 역할이 cors 미들웨어 이다.

const cors = require('cors')

// 생략
app.use(cors()) // 모든 요청에 대해 CORS 허용
const cors = require('cors')

// 생략
// 특정 요청에 대해 CORS 허용
app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

미들웨어 작동원리 이해하기

case 1: 모든 요청에 대해 url이나 메소드를 알고자 할 때

가장 단순한 미들웨어는 logger이다. console.log와 같이 디버깅이나 서버 관리에 도움이 되기 위해 log를 찍어주는 역할을 합니다.

미들웨어 함수 안의 파라미터 순서대로 진행이 되는데, req,res는 요청/응답을 의미하고 next는 다음 컨베이어벨트로 넘기는 작업을 한다. 위 함수에서는 next()를 호출해서 다음 컨베이어 벨트로 넘길 뿐, 아무런 일을 하지 않고 있다.

이번엔 특정 endpoint가 아닌, 모든 요청에 대해서 미들웨어를 붙여보자. 이때에는 app.use라는 메소드를 이용한다. 아래 코드를 직접 실행하여. 모든 요청에 대해 LOGGED가 콘솔에 찍히는 것을 확인해야한다.

목표는 아래와같이 모든 요청에 대한 메소드와 url을 찍어야 한다.

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

const myLogger = function (req, res, next) {
  console.log('LOGGED'); 
  // 이 부분을 req, res 객체를 이용해 고치면, 모든 요청에 대한 로그를 찍을 수 있습니다.
  next();
};

app.use(myLogger);

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000);

해당 Logging 부분은 추후 morgan 이나 winston 모듈을 이용해서 편리하게 사용할 수 있다. (라이브러리 설치)

morgan 참조
winston 참조

case 4: 요청 헤더에 사용자 인증 정보가 담겨있는지 확인하고 싶을 때

HTTP요청에서 토큰(사용자인증을 위해 쓰는 것)이 있는지 여부를 판단하여, 이미 로그인한 사용자는 '성공' 아닌 경우 '에러'를 보내는 미들웨어이다.

app.use((req, res, next) => {
  // 토큰 있니? 없으면 받아줄 수 없어!
  if(req.headers.token){
    req.isLoggedIn = true;
    next()
  } else {
    res.status(400).send('invalid user')
  }
})

참조사이트
[Node.JS] 강좌 09편: Express 프레임워크 사용해보기
심화 : [Node.JS] 강좌 10-1편: Express 프레임워크 응용하기 – EJS

profile
차곡차곡 쌓아가는 나의 개발 기록

0개의 댓글