Express

김동현·2021년 7월 18일
1

Server & Node

목록 보기
2/6


Express.js 는 Node.js 환경에서 웹 어플리케이션 혹은 API를 제작하기 위해 사용되는 인기있는 프레임워크이다

express가 기존 http 모듈로 작성했던 서버와 갖는 큰 차이점은

  1. 미들웨어를 붙이기 쉽다.
  2. 자체 라우터를 제공한다.

npm istall express —save 를 통해 설치

const express = require('express')
const app = express()
const port = 3000

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

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

기본 라우팅

app.get('/', function (req, res) {
  res.send('Hello World!');
});
// 홈페이지에서 Hello World! 로 응답

app.post('/', function (req, res) {
  res.send('Got a POST request');
});
// 에플리케이션의 홈페이지인 루트 라우트(/)에서 POST요청에 응답

app.put('/user', function (req, res) {
  res.send('Got a PUT request at /user');
});
// /user 라우트에 대한 PUT요청에 응답

app.delete('/user', function (req, res) {
  res.send('Got a DELETE request at /user');
});
// /user 라우트에 대한 DELETE 요청에 응답

미들웨어(middleware)

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

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

case 2: POST 요청 등에서 쓰이는 body(payload)를 쉽게 얻어내고자 할 때

앞서 순수 node.js 코드로 HTTP body(payload)를 받을 때에는 Buffer를 조합해서 다소 복잡한 방식으로 body를 얻어내야만 한다.

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // body 변수에는 문자열 형태로 payload가 담겨져 있습니다.
});

이를 쉽게 만들어주는 역할을 하는 것이 바로 body-parser 미들웨어 이다.

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

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

case 4: 모든 요청/응답에 CORS 헤더를 붙일 때

앞서 순수 node.js 코드로 CORS 헤더를 붙이려면, 응답 객체의 writeHead 메소드 등을 이용해 일일이 Access-Control-Allow-* 헤더를 정의해줘야만 했으며, OPTIONS 메소드에 대한 라우팅도 구현해줘야만 했다.

const defaultCorsHeader = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Accept',
  'Access-Control-Max-Age': 10
};

// 생략
if (req.method === 'OPTIONS') {
  res.writeHead(201, defaultCorsHeader);
  res.end()
}

이를 쉽게 만들어주는 역할을 하는 것이 바로 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를 적절하게 찍어주는 역할을 합니다. 미들웨어는 다음 구성을 가집니다.

위 그림은 endpoint가 /이면서, GET 요청을 받았을 때에, 사용하는 미들웨어이다.

주목할 것은 파라미터 순서이다.

req, res는 우리가 잘 아는 요청/응답이며, next는 다음 컨베이어 벨트로 넘기는 작업을 한다. (왼쪽의 그림을 참고)

현재 미들웨어 내부에서는 아무런 일도 하고 있지 않는다. 그저 next() 함수를 호출하여 다음 컨베이어 벨트로 넘길 뿐.

이번엔 특정 endpoint가 아닌, 모든 요청에 대해서 미들웨어를 붙여보자.

이때에는 app.use라는 메소드를 이용한다.

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);

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

다음은 HTTP 요청에서 토큰이 있는지 여부를 판단하여, 이미 로그인한 사용자일 경우 성공, 아닐 경우 에러를 보내는 미들웨어 예제이다.

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

0개의 댓글