Express로 간단한 서버를 구현할 수 있다.
미들웨어를 이해할 수 있다.
미들웨어를 이용할 수 있다.
미들웨어를 구현할 수 있다.
npm install express
로 우선 express를 설치한다.
// 응답으로 'Hello World!' 를 보내는 Express 서버 코드
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 on port ${port}`)
})
라우팅(Routing): 메서드와 url(/lower, /upper 등)로 분기점을 만드는 것
클라이언트는 특정한 HTTP 요청 메서드(GET, POST 등)와 함께 서버의 특정 URI(또는 경로)로 HTTP 요청을 보내게 되는데,
라우팅은 클라이언트의 요청에 해당하는 Endpoint에 따라 서버가 응답하는 방법을 결정하는 것이다.
const requestHandler = (req, res) => { if(req.url === '/lower') { if (req.method === 'GET') { res.end(data) } else if (req.method === 'POST') { req.on('data', (req, res) => { // do something ... }) } } }
const router = express.Router() router.get('/lower', (req, res) => { res.send(data); }) router.post('/lower', (req, res) => { // do something ... })
미들웨어는 express의 가장 큰 장점
미들웨어(Middleware)는 자동차 공장의 공정과 비슷하다.
컨베이어 벨트 위에 올라가 있는 요청(Request)에 필요한 기능을 더하거나, 문제가 발견된 불량품을 밖으로 걷어내는 역할
미들웨어를 이용하면 Node.js 만으로 구현한 서버에서는 번거로울 수 있는 작업을 보다 쉽게 적용할 수 있다.
미들웨어를 사용하는 4가지 상황
let body = []; request.on('data', (chunk) => { body.push(chunk); }).on('end', () => { body = Buffer.concat(body).toString(); // body 변수에는 문자열 형태로 payload가 담겨져 있다 });
- Node.js로 HTTP 요청 body를 받는 코드 (다소 복잡하다!)
위 Node.js로 짠 코드는, body-parser 미들웨어
를 사용하면 더 간단하게 처리할 수 있다.
우선 설치해주자.
npm install body-parser
const bodyParser = require('body-parser'); const jsonParser = bodyParser.json(); // 생략 app.post('/users', jsonParser, function (req, res) { })
- body-parser를 미들웨어를 이용한 코드
- 더 간단하게 처리가 가능함을 알 수 있다!
Express v4.16.0 부터는 body-parser
를 따로 설치하지 않고, Express 내장 미들웨어인 express.json()
을 사용한다.
const jsonParser = express.json(); // 생략 app.post('/api/users', jsonParser, function (req, res) { })
express.json()
을 이용한 코드
Node.js HTTP 모듈을 이용한 코드에 CORS 헤더를 붙이려면, 응답 객체의 writeHead
메서드를 이용할 수 있다.
Node.js에서는 이 메서드 등을 이용하여 라우팅마다 헤더를 매번 넣어주어야 한다. 그뿐만 아니라, 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(200, defaultCorsHeader); res.end() }
- Node.js에 CORS를 적용하는 예시
- 라우팅마다 매번
res.writeHead(200, defaultCorsHeader);
적어줘야 함
BUT! cors 미들웨어
를 사용하면 이 과정을 간단하게 처리 가능하다!
우선 설치해 주자
npm install cors
const cors = require('cors'); // 생략 app.use(cors());
- 모든 요청에 대해 CORS 허용
const cors = require('cors') // 생략 app.get('/products/:id', cors(), function (req, res, next) { res.json({msg: 'This is CORS-enabled for a Single Route'}) })
- 특정 요청에 대해 CORS 허용
로거는 디버깅이나, 서버 관리에 도움이 되기 위해 console.log
로 적절한 데이터나 정보를 출력해준다.
데이터가 여러 미들웨어를 거치는 동안 응답할 결과를 만들어야 한다면,
미들웨어 사이사이 로거를 삽입해 현재 데이터를 확인하거나, 디버깅에 사용할 수 있다.
위 그림은 endpoint가 /이면서, 클라이언트로부터 GET 요청을 받았을 때 적용되는 미들웨어이다.
파라미터의 순서에 유의하자!!
req, res는 우리가 잘 아는 요청(request), 응답(response)이고
next는 다음 미들웨어를 실행하는 역할!
만약 특정 endpoint가 아닌, 모든 요청에 동일한 미들웨어를 적용하려면?
➡ 메서드 app.use 를 사용하면 된다!!!
const express = require('express'); const app = express(); const myLogger = function (req, res, next) { console.log('LOGGED'); next(); }; app.use(myLogger); app.get('/', function (req, res) { res.send('Hello World!'); }); app.listen(3000);
- use 메서드로 모든 요청에 대하여 미들웨어를 적용
- 모든 요청에 대해
LOGGED
가 출력되는 걸 확인할 수 있다
다음은 HTTP 요청에서 토큰이 있는지를 판단하여, 이미 로그인한 사용자일 경우 성공, 아닐 경우 에러를 보내는 미들웨어 예제
app.use((req, res, next) => {
// 토큰이 있는지 확인, 없으면 받아줄 수 없음.
if(req.headers.token){
req.isLoggedIn = true;
next();
} else {
res.status(400).send('invalid user')
}
})
로그인 없이 웹사이트에 접근을 시도했을 때, 로그인 창으로 되돌려 보내는 경우가 있다.
이와 같이 서버에서는 요청에 포함된 데이터를 통해 미들웨어가 요구하는 조건에 맞지 않으면, 불량품으로 판단하고 돌려보내도록 할 수 있다.