순서가 중요합니다
Coddy Node.js 여정의 Express 기초 섹션에 포함된 레슨. 23개 중 14번째.
Express는 코드에서 미들웨어와 경로를 추가한 순서대로 실행하며, 응답하는 경로는 그 지점에서 요청 처리를 끝냅니다.
app.get('/bikes', (req, res) => {
res.json(bikes);
});
app.use((req, res, next) => {
res.set('Cache-Control', 'no-store');
next();
});res.set(name, value)는 응답에 헤더를 추가하며, 응답을 보내기 전에 실행해야 합니다. 여기서는 미들웨어에 도달하기 전에 GET /bikes가 응답하므로, 해당 응답에는 헤더가 포함되지 않습니다. 미들웨어는 위쪽에 있는 경로가 응답하지 않은 요청만 확인합니다. 모든 응답에 적용되어야 하는 미들웨어는 경로와 express.static보다 위에 둡니다.
챌린지
쉬움각 응답에는 ID가 포함되므로 방문자가 문제를 신고하면 로그에서 해당 요청을 찾을 수 있습니다. 페이지, API 데이터, public의 파일 등 모든 응답에 ID가 필요합니다.
server.js에서node:crypto로부터randomUUID를 가져오세요. 호출할 때마다3b241101-e2bb-4255-8caf-4136c566a962와 같은 새로운 임의 ID를 반환합니다.- 응답 헤더
X-Request-Id를 설정하는 미들웨어를 추가하세요. 이 헤더에는 요청마다 새randomUUID()가 담기며, 그런 다음next()를 호출합니다. - 모든 요청이 이 미들웨어를 거치도록 배치하세요. 여기에는
express.static이 전송하는 파일도 포함됩니다. 미들웨어가 응답이 생성되기 전에 실행되는 경우에만 응답에 헤더가 추가됩니다.
직접 해보기: ‘실행’을 누르고 /api/recipes를 두 번 전송하세요. Headers 탭에서 X-Request-Id 값이 매번 다릅니다. /style.css와 /도 전송해 보세요. 각 응답에도 X-Request-Id가 포함됩니다.
직접 해보기
import { escapeHtml } from './html.js';
import express from 'express';
import { recipes } from './data.js';
const app = express();
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
app.use(express.static('public'));
app.get('/', (req, res) => {
const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
res.send(`<link rel="stylesheet" href="/style.css"><h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});
// type('text')는 일반 텍스트를 전송하므로 각 제목이 한 줄씩 표시됩니다.
app.get('/recipes', (req, res) => {
const { tag } = req.query;
const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});
app.get('/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).send('No such recipe');
return;
}
res.send(recipe.title);
});
app.get('/api/recipes', (req, res) => {
res.json(recipes);
});
app.get('/api/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).json({ error: 'No such recipe' });
return;
}
res.json(recipe);
});
app.get('/about', (req, res) => {
res.send('Recipe Box collects family recipes.');
});
app.get('/menu', (req, res) => {
res.redirect(301, '/recipes');
});
app.get('/menu/:id', (req, res) => {
res.redirect(301, `/recipes/${req.params.id}`);
});
app.listen(3000, () => {
console.log('Recipe Box is running on port 3000');
});
Express 기초의 모든 레슨
직접 연습해 보세요: Express 플레이그라운드