5. 라우팅과 요청/응답 다루기
Worker는 결국 하나의 함수이기 때문에, 여러 URL 경로나 HTTP 메서드를 처리하려면 직접 분기 처리를 해야 합니다.
5.1 URL로 분기하기
Request.url을 표준 URL 객체로 파싱해서 pathname을 확인합니다.
js
export default { async fetch(request, env, ctx) { const url = new URL(request.url); if (url.pathname === "/") { return new Response("홈페이지"); } if (url.pathname === "/api/hello") { return Response.json({ message: "Hello!" }); } return new Response("Not Found", { status: 404 }); }, };
이 강의의 sample-worker/src/index.js가 정확히 이 패턴으로 작성되어 있습니다.
5.2 HTTP 메서드로 분기하기
request.method로 GET/POST/PUT/DELETE 등을 구분할 수 있습니다.
js
export default { async fetch(request, env, ctx) { const url = new URL(request.url); if (url.pathname === "/api/items") { if (request.method === "GET") { return Response.json({ items: ["apple", "banana"] }); } if (request.method === "POST") { const body = await request.json(); return Response.json({ created: body }, { status: 201 }); } return new Response("Method Not Allowed", { status: 405 }); } return new Response("Not Found", { status: 404 }); }, };
5.3 요청 본문(body) 읽기
Request는 표준 Fetch API를 따르므로 아래처럼 다양한 형태로 body를 읽을 수 있습니다.
js
const json = await request.json(); // JSON body const text = await request.text(); // 순수 텍스트 const formData = await request.formData(); // form-data
5.4 응답(Response) 만들기
js
// 텍스트 응답 new Response("plain text"); // JSON 응답 (Content-Type 자동 설정) Response.json({ ok: true }); // 상태 코드와 헤더 지정 new Response("Created", { status: 201, headers: { "X-Custom-Header": "value" }, }); // 리다이렉트 Response.redirect("https://example.com", 302);
5.5 라우터 라이브러리를 쓰고 싶다면
프로젝트가 커지면 직접 if문으로 분기하는 대신 경량 라우터를 쓰는 것도 좋은 선택입니다. Workers 생태계에서 널리 쓰이는 라이브러리:
- Hono — Express와 비슷한 API를 제공하는 초경량 웹 프레임워크, Workers를 1급으로 지원
- itty-router — 아주 가벼운 라우터
js
// Hono 예시 import { Hono } from "hono"; const app = new Hono(); app.get("/", (c) => c.text("홈페이지")); app.get("/api/hello", (c) => c.json({ message: "Hello!" })); export default app;