Express는 Node.js 환경에서 웹 서버, 또는 API 서버를 제작하기 위해 사용되는 프레임 워크다. Express로 구현한 서버가 HTTP 모듈로 작성한 서버와 다른 점은 아래 두 가지가 있다.
메서드와 url로 분기점을 만드는 것을 라우팅(Routing)이라고 한다.
클라이언트는 특정한 HTTP 요청 메서드 (GET, POST 등)와 함께 서버의 특정 url로 HTTP 요청을 보낸다. 라우팅은 클라이언트의 요청에 해당하는 Endpoint에 따라 서버가 응답하는 방법을 결정하는것이다.
// Node.js로 라우팅을 구현한 코드
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 ...
})
}
}
}
Express의 라우터를 활용하면 더 직관적으로 작성할 수 있다.
// Express로 라우팅을 구현한 코드
onst router = express.Router()
router.get('/lower', (req, res) => {
res.send(data);
})
router.post('/lower', (req, res) => {
// do something
})
Express는 미들웨어를 추가할 수 있다고 했다. 그럼 이 미들웨어는 무엇일까?
미들웨어는 양 쪽을 연결하여 데이터를 주고 받을 수 있도록 중간에서 매개 역할을 하고 네트워크를 통해서 연결된 여러 개의 컴퓨터에 있는 많은 프로세스들에게 어떤 서비스를 사용할 수 있도록 연결해 주는 소프트웨어를 말한다. 웹 브라우저에서 데이터베이스로부터 데이터를 저장하거나 읽어올 수 있게 중간에 미들웨어가 존재하게 된다.
정리하면 미들웨어는 양쪽을 연결해 주는 매개 역할이라 할 수 있다.미들 웨어를 사용하는 경우는 네가지로 나뉜다.
1. POST 요청 등에 포함된 body를 구조화 할 때
2. 모든 요청/응답에 CORS 헤더를 붙여야 할 때
3. 모든 요청에 대해 url이나 메서드를 확인할 때
4. 모든 헤더에 사용자 인증 정보가 담겨있는지 확인할 때
// 서버 실행
node server/basic-server.js
// nodemon 설치
npm install nodemon
// package.json의 scripts에 아래 코드 추가
"start": "nodemon server/basic-server.js"
// nodemon으로 서버 실행
npx nodemon server/basic-server.js
Endpoint(URL) | Method | 기능 |
---|---|---|
/lower | POST | 문자열을 소문자로 만들어 응답 |
/upper | POST | 문자열을 대문자로 만들어 응답 |
const http = require("http");
const PORT = 4999;
const ip = "localhost";
const server = http.createServer((request, response) => {
if (request.method === "OPTIONS") {
response.writeHead(200, defaultCorsHeader);
response.end();
}
if (request.method === "POST" && request.url === "/upper") {
let body = [];
request
.on("data", (chunk) => {
body.push(chunk);
})
.on("end", () => {
body = Buffer.concat(body).toString().toUpperCase();
response.writeHead(200, defaultCorsHeader);
response.end(body);
});
} else if (request.method === "POST" && request.url === "/lower") {
let body = [];
request
.on("data", (chunk) => {
body.push(chunk);
})
.on("end", () => {
body = Buffer.concat(body).toString().toLowerCase();
response.writeHead(200, defaultCorsHeader);
response.end(body);
});
} else {
request.on("error", (err) => {
response.writeHead(404, defaultCorsHeader);
console.error(err, "bad request");
});
}
});
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,
};
const express = require("express");
const cors = require("cors");
const app = express();
app.use(express.json({strict: false})); //JSON 데이터를 처리하는 미들웨어 등록
const PORT = 4999;
const ip = "localhost";
// 모든 요청과 응답에 헤더 붙임
app.use(cors());
//post요청 : /upper
app.post("/upper", function (req, res) {
res.status(201).json(req.body.toUpperCase());
});
//post요청 : /lower
app.post("/lower", function (req, res) {
res.status(201).json(req.body.toLowerCase());
});
// 404 에러처리
app.use((req, res, next) => {
res.status(404).send("Error");
});
app.listen(PORT, ip, () => {
console.log(`http server listen on ${ip}:${PORT}`);
});
express를 활용하니 node.js보다 훨씬 간결해졌다.
또 미들웨어와 라우터를 사용해 편리하게 웹 서버를 구성할 수 있다.
upper, lower 둘다 정상 작동하는 것을 확인할 수 있다.