Daten & Route-Handler

Stelle Deployments über app/api bereit, rufe sie in einer Seite ab und lege neue per POST an.

Die App dieses Kapitels läuft in deiner Konsole. Öffne sie mit ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C (zuerst Entwicklerfunktionen aktivieren), dann probiere sie aus.
Kapitel ansehen3:32

In diesem Kapitel

  • Ein Route-Handler
  • Daten in einer Seite abrufen
  • Lade- und Fehlerzustände
  • Streaming

Acme Deploys braucht echte Daten. Route-Handler liegen neben deinen Seiten in app/, verwenden die Web-APIs Request und Response und laufen unter text dev und text start. Sie teilen sich den Origin der App, daher brauchen Anfragen keine CORS-Konfiguration.

Ein Route-Handler

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

Rufe ihn über die Eingabezeile der Konsole auf, während text dev läuft:

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

Daten in einer Seite abrufen

Rufe Daten in einem Effekt ab und zeige einen <Spinner>, bis die Daten eintreffen. r ruft die Daten erneut ab; n sendet per POST ein neues Deployment, das zunächst als im Build angezeigt wird und nach Abschluss des Builds als bereit erscheint.

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

Lade- und Fehlerzustände

Statt loading von Hand zu verwalten, zeigt eine loading.tsx neben der Seite den Ladezustand an, während die Seite pausiert, und error.tsx fängt alle Fehler ab, die sie wirft. Beide sind normale Komponenten:

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

Streaming

Handler können einen ReadableStream zurückgeben, über den Build-Logs Zeile für Zeile ins Dashboard streamen. Unter Route-Handler findest du Informationen zu Server-Sent Events und zur Proxy-Anbindung eines lokalen Daemons.

Ausprobieren

Das ist Acme Deploys am Ende des Kapitels, ausgeführt in DevTools. Klicke auf das Pad und nutze dann die Tasten unten.

▼ 06 · Daten & Route-Handler

Die Konsole öffnen

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

Die App rendert in DevTools.Aktiviere zuerst „Funktionen für Webentwickler anzeigen“ unter Safari Einstellungen → Erweitert. Klicke dann hier und drücke r.

Auf einem Desktop öffnen

Diese App rendert in der DevTools-Konsole, die einen Desktop-Browser benötigt.

Quiz

2 Fragen

Beantworte jede Frage, um das Kapitel abzuschließen.

Was geben Route-Handler zurück?

 

Welche Datei erscheint, während eine Route pausiert?