버전 관리
Coddy Node.js 여정의 REST API 섹션에 포함된 레슨. 18개 중 15번째.
응답의 구조를 바꾸면 이미 이를 사용 중인 모든 클라이언트가 영향을 받습니다. 경로에 버전을 넣으면 기존 클라이언트와 새 클라이언트가 나란히 사용할 수 있습니다. 오늘은 /api/v1/orders, 구조가 바뀌면 /api/v2/orders를 사용합니다. 경로가 이동하면 리디렉션 응답을 반환합니다.
GET /api/orders/5 → 308 Location: /api/v1/orders/5
POST /api/orders → 308 Location: /api/v1/orders301과 302를 사용하면 클라이언트가 POST 요청을 GET 요청으로 다시 보낼 수 있으며, 이때 본문이 사라집니다. 308은 메서드와 본문을 포함해 "같은 요청을 해당 위치로 다시 보내라"고 নির্দেশ합니다. 마운트된 미들웨어 안에서는 req.url에서 마운트 경로가 빠지지만, req.originalUrl에는 전체 경로가 유지됩니다.
// GET /api/orders/5?full=1 요청에서 app.use('/api/orders', ...) 내부
req.url // '/5?full=1'
req.originalUrl // '/api/orders/5?full=1'챌린지
쉬움- 작업 라우터를
/api/v1/tasks에 마운트합니다. - 기존의 모든
/api/tasks경로는 쿼리를 포함하여/api/v1아래의 동일한 경로로 308 응답을 반환합니다. - 새 작업에는
Location: /api/v1/tasks/<id>가 설정됩니다.
GET /api/tasks/2를 보내고, { "title": "Order new chairs" }를 사용하여 POST /api/tasks를 보낸 다음, GET /api/v1/tasks/2를 보냅니다.
직접 해보기
import express from 'express';
import { sendError } from './errors.js';
import taskRoutes from './routes/tasks.js';
const BOARD_ORIGIN = 'https://board.example.com';
const app = express();
app.use(express.json());
// BOARD_ORIGIN의 페이지가 브라우저에서 이 API를 호출할 수 있게 합니다.
app.use((req, res, next) => {
res.set('Access-Control-Allow-Origin', BOARD_ORIGIN);
res.set('Access-Control-Allow-Credentials', 'true');
if (req.method === 'OPTIONS') {
res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE');
res.set('Access-Control-Allow-Headers', 'Content-Type');
return res.status(204).end();
}
next();
});
app.use(express.static('public'));
app.use('/api/tasks', taskRoutes);
// 라우트에서 발생한 오류는 여기서 처리됩니다. 유효한 JSON이 아닌 본문은
// 클라이언트의 잘못입니다(400). 그 밖의 오류는 서버의 잘못입니다(500).
app.use((err, req, res, next) => {
if (err.type === 'entity.parse.failed') {
return sendError(res, 400, 'invalid_json', 'The body is not valid JSON');
}
console.error(err);
sendError(res, 500, 'server_error', 'Something went wrong');
});
app.listen(3000, () => {
console.log('Task tracker API on port 3000');
});