
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')
}
})
로그인 없이 웹사이트에 접근을 시도했을 때, 로그인 창으로 되돌려 보내는 경우가 있다.
이와 같이 서버에서는 요청에 포함된 데이터를 통해 미들웨어가 요구하는 조건에 맞지 않으면, 불량품으로 판단하고 돌려보내도록 할 수 있다.