Hirefullstack – Software Engineering & IT-Beratung aus Berlin
← Zur Übersicht
Kern 10 Min Lesezeit

Route Handler

Wenn etwas von außen zugreifen soll

In einem Satz

Eine route.ts antwortet auf eine Adresse mit Daten statt mit einer Seite. Gedacht für Zugriffe von außen – nicht für deine eigene Oberfläche.

Lesen macht die Server-Komponente, Schreiben die Server Action. Bleibt eine Lücke: Was, wenn ein fremdes System mit dir reden will? Dafür gibt es den Route HandlerEine `route.ts`, die auf eine Adresse antwortet, ohne eine Seite zu sein – der Weg zu einer eigenen API..

app/api/artikel/route.ts
export async function GET() {
  const artikel = await db.artikel.findMany();
  return Response.json(artikel);
}

export async function POST(request: Request) {
  const daten = await request.json();
  const neu = await db.artikel.create({ data: daten });
  return Response.json(neu, { status: 201 });
}
Die Datei heißt route.ts, die Funktionen heißen wie die HTTP-Methoden. Zurück kommt eine ganz normale Response.
Stolperstein page.tsx und route.ts vertragen sich nicht

In einem Ordner darf nur eines von beidem liegen. Eine Adresse ist entweder eine Seite oder ein Endpunkt. Deshalb legt man Handler üblicherweise unter app/api/… ab.

Wofür wirklich

Nimm es, wenn …
  • +

    Webhooks: Zahlungsanbieter, Redaktionssystem, GitHub melden sich bei dir

  • +

    Eine öffentliche Schnittstelle für fremde Systeme oder eine mobile App

  • +

    Dateien ausliefern: Bilder erzeugen, PDF, CSV-Export

  • +

    OAuth-Rückleitungen und ähnliche Umleitungen

Lass es, wenn …
  • Die eigene Server-Komponente ruft die eigene Route auf – ein Netzwerkumweg zu sich selbst

  • Formulare der eigenen Oberfläche – dafür sind Server Actions kürzer und sicherer

  • Daten für die eigene Client-Komponente, die auch von oben hereingereicht werden könnten

Bildlich gesprochen

Server Actions sind die Haustür für die eigene Familie – kurz, direkt, ohne Formalitäten. Ein Route Handler ist der Lieferanteneingang: dokumentiert, mit Adresse, für Leute von außerhalb.

Was drin steckt

app/api/suche/route.ts
export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const q = searchParams.get("q") ?? "";

  if (!q) {
    return Response.json({ fehler: "q fehlt" }, { status: 400 });
  }

  const treffer = await db.artikel.findMany({
    where: { titel: { contains: q } },
  });

  return Response.json(treffer);
}
app/api/artikel/[id]/route.ts
export async function DELETE(
  request: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  const { id } = await params;      // auch hier: erst awaiten
  await db.artikel.delete({ where: { id } });
  return new Response(null, { status: 204 });
}
Achtung Route Handler sind vollständig öffentlich

Anders als bei einer Seite steht hier kein Layout und keine Prüfung davor. Wer die Adresse kennt, kann sie aufrufen. Jeder Handler prüft also selbst: Ist ein gültiger Schlüssel dabei? Stimmt die Signatur des Webhooks? Darf diese Person das?

Zwischenspeichern

cache.ts
// GET-Handler sind standardmäßig dynamisch – jede Anfrage läuft durch.
// Willst du das Ergebnis zwischenspeichern:
export const revalidate = 60;

// Umgekehrt ausdrücklich immer frisch:
export const dynamic = "force-dynamic";
Genauer erklärt: ein Webhook mit Revalidierung optional

Der häufigste sinnvolle Einsatz: Ein Redaktionssystem meldet, dass etwas veröffentlicht wurde, und deine Seite räumt daraufhin den passenden Zwischenspeicher ab.

app/api/revalidate/route.ts
import { revalidateTag } from "next/cache";

export async function POST(request: Request) {
  const schluessel = request.headers.get("x-webhook-key");
  if (schluessel !== process.env.WEBHOOK_KEY) {
    return new Response("Nicht erlaubt", { status: 401 });
  }

  const { typ } = await request.json();
  revalidateTag(typ);                 // z. B. "artikel"

  return Response.json({ ok: true });
}
Tipp Den Schlüssel wirklich prüfen

Ohne die erste Prüfung könnte jeder deine Seite beliebig oft neu bauen lassen. Der Schlüssel gehört in eine Umgebungsvariable ohne NEXT_PUBLIC_ – sonst landet er im Browser.

Sitzt das schon?

4 Fragen zu dieser Lektion. Falsche Antworten landen in deiner Statistik.

Hirefullstack

Ihr braucht React-Verstärkung im Team?

Wir bauen seit Jahren React- und Next.js-Anwendungen für Kunden in ganz Deutschland – als einzelner Experte, als Verstärkung fürs Bestandsteam oder als komplettes Scrum-Team.

Projekt besprechen →