Daten & Route-Handler
Stelle Deployments über app/api bereit, rufe sie in einer Seite ab und lege neue per POST an.
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
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.
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:
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.
Die Konsole öffnen
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 FragenBeantworte jede Frage, um das Kapitel abzuschließen.