GodLights Study

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 생태계에서 널리 쓰이는 라이브러리:

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;

참고 자료

➡️ 다음: 환경 변수와 시크릿 ⬅️ 이전: 로컬에서 개발하고 테스트하기