Express를 활용한 미들웨어 예제
1.POST요청 등에 포함된 body(payload)를 구조화 할때
순수 node.js로 HTTP body(payload)를 받을 때에는 Buffer를 조합하여 다소 복잡한 방식으로 body를 쓸수 있다.
// 네트워크상의 chunk를 합치고, buffer를 body로 변환하는 작업이 필요
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
});
이를 body-parser 미들웨어를 사용하면 간단하게 처리할 수있다.(express 4.16이상 부터는 body-parser 미들웨어가 따로 필요 없고 express내부에 포함되어 있다.)
express.json([option])
2.모든 요청/응답에 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 허용
// 특정 요청에만 허용
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS'})
})
모든 요청에 대해 url이나 메소드를 확인할 때
모든 요청에 동일한 미들웨어를 적용하려면 app.use
메소드를 사용하면 된다.
const express = require('express');
const app = express();
const myLogger = function (req, res, next) {
console.log(); // req, res객체를 이용하면, 모든 요청에 대한 로그를 찍을 수 있다.
next();
}
app.use(myLogger);
//생략
예제 실습 - Mini Node Server에 리팩토링
Mini node Server(순수 node.js)
const http = require('http');
const PORT = 4999;
const ip = 'localhost';
const server = http.createServer((req, res) => {
if (req.method === 'OPTIONS') {
res.writeHead(200, defaultCorsHeader);
res.end();
}
if (req.method === 'POST') {
let body = [];
req.on('data', (chunk) => {
body.push(chunk);
})
.on('end', () => {
body = Buffer.concat(body).toString();
res.writeHead(201, defaultCorsHeader);
if (req.url === '/upper') { // 대문자
res.end(body.toString());
}
else if (req.url === '/lower') { // 소문자
res.end(body.toString());
}
else {
res.writeHead(404, defaultCorsHeader);
res.end();
}
})
}
});
server.listen(PORT, ip, () => {
console.log(`http server listen on ${ip}:${PORT}`);
});
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
};
Express로 리팩토링
const express = require('express')
const app = express();
const cors = require('cors')
const PORT = 3999;
const ip = 'localhost';
app.use(cors()); // 모든 요청/응답에 CORS 처리
// 자동 바디 퍼싱
// strict 옵션은 비활성화면 모든 것을 받을수 있다.
app.use(express.json({strict: false}))
app.post('/upper', function (req, res) {
let newBody = req.body;
newBody = newBody.toUpperCase();
res.json(newBody); // 데이터를 보내줄 때 json화
}
app.post('/lower', function (req, res) {
let newBody = req.body;
newBody = newBody.toLowerCase();
res.json(newBody); // 데이터를 보내줄 때 json화
}
app.use( function (req, res, next) {
// 클라이언트의 잘못으로 인한 404에러는 err인자가 포함되지 않는다.
res.status(404).send('Error 404');
});
app.use( function (err, req, res, next) {
// 에러 처리
res.status(500).send('Error 500');
}