데이터와 라우트 핸들러

app/api에서 배포 데이터를 제공하고, 페이지에서 가져오고, 새 데이터를 전송하세요.

이 장의 앱이 콘솔에서 실행 중이에요. ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C로 콘솔을 열고 (먼저 개발자 기능을 켜세요), 사용해 보세요.
장 동영상 보기3:32

이 장의 내용

  • 라우트 핸들러
  • 페이지에서 데이터 가져오기
  • 로딩 및 오류 상태
  • 스트리밍

Acme Deploys에는 실제 데이터가 필요해요. 라우트 핸들러는 app/에서 페이지 옆에 위치하고, 웹 Request와 Response API를 사용하며, text dev와 text start에서 실행돼요. 앱과 출처가 같아서 요청에 CORS 설정이 필요 없어요.

라우트 핸들러

app/api/deployments/route.ts+10ts
추가: import { DEPLOYMENTS, createDeployment } from "../../../lib/deployments";추가: 추가: export function GET(): Response {추가:   return Response.json(DEPLOYMENTS);추가: }추가: 추가: export async function POST(req: Request): Promise<Response> {추가:   const deployment = createDeployment(await req.json());추가:   return Response.json(deployment, { status: 201 });추가: }

text dev가 실행 중일 때 콘솔 프롬프트에서 호출하세요:

await (await fetch("/api/deployments")).json()

페이지에서 데이터 가져오기

이펙트에서 데이터를 가져오고 데이터가 도착할 때까지 <Spinner>를 표시하세요. r은 데이터를 다시 가져오고, n은 새 배포를 POST 요청으로 생성해요. 새 배포는 빌드 중으로 표시되다가 빌드가 끝나면 준비 완료로 바뀌어요.

app/deployments/page.tsx+21-2tsx
삭제: import { DEPLOYMENTS } from "../../lib/deployments";추가: import { useEffect, useState } from "react";추가: import { Spinner, useInput } from "@textjs/app";추가: import type { Deployment } from "../../lib/deployments";export default function DeploymentsPage() {추가:   const [rows, setRows] = useState<Deployment[]>([]);추가:   const [loading, setLoading] = useState(true);추가: 추가:   const refetch = async () => {추가:     setLoading(true);추가:     setRows(await (await fetch("/api/deployments")).json());추가:     setLoading(false);추가:   };추가:   useEffect(() => void refetch(), []);추가: 추가:   useInput((e) => {추가:     if (e.input === "r") void refetch();추가:     if (e.input === "n") void fetch("/api/deployments", { method: "POST", body: "{}" }).then(refetch);추가:   });추가: 추가:   if (loading) return <Spinner label="Loading deployments…" />;  return (    <Box className="flex-col">삭제:       {DEPLOYMENTS.map((d) => (추가:       {rows.map((d) => (        <Box key={d.id} className="flex-row h-1 gap-2">추가:           <Status status={d.status} />          …

로딩 및 오류 상태

loading을 직접 처리하는 대신, 페이지가 일시 중단된 동안 페이지 옆의 loading.tsx가 표시되고 error.tsx가 페이지에서 발생하는 모든 오류를 잡아요. 둘 다 일반 컴포넌트예요:

app/deployments/loading.tsxtsx
import { Spinner } from "@textjs/app";export default function Loading() {  return <Spinner label="Loading deployments…" />;}

스트리밍

핸들러는 ReadableStream을 반환할 수 있어요. 빌드 로그도 이 방식으로 대시보드에 한 줄씩 스트리밍돼요. 서버 전송 이벤트와 로컬 데몬 프록시는 라우트 핸들러를 참고하세요.

사용해 보기

이 장을 마쳤을 때의 Acme Deploys 앱이 DevTools에서 실행 중이에요. 패드를 클릭한 뒤 아래 키를 사용하세요.

▼ 06 · 데이터와 라우트 핸들러

콘솔 열기

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

앱은 DevTools에서 렌더링돼요.먼저 Safari 설정 → 고급에서 ‘웹 개발자용 기능 보기’를 켜세요. 그다음 여기를 클릭하고 r을 누르세요.

데스크톱에서 열기

이 앱은 DevTools 콘솔에서 렌더링되므로 데스크톱 브라우저가 필요해요.

퀴즈

질문 2개

장을 완료하려면 모든 문제에 답하세요.

라우트 핸들러는 무엇을 반환하나요?

 

라우트가 일시 중단되면 어떤 파일이 표시되나요?