Deutsch

Lernen Sie, wie Sie mit Next.js Route Handlers leistungsstarke API-Endpunkte erstellen. Dieser Leitfaden deckt alles ab, von der Grundeinrichtung bis hin zu fortgeschrittenen Techniken, mit praktischen Beispielen und Best Practices.

Next.js Route Handlers: Ein umfassender Leitfaden zur Erstellung von API-Endpunkten

Next.js hat die Art und Weise, wie wir Webanwendungen erstellen, mit seinen leistungsstarken Funktionen wie serverseitigem Rendern, statischer Seitengenerierung und jetzt auch Route Handlers revolutioniert. Route Handlers bieten eine flexible und effiziente Möglichkeit, API-Endpunkte direkt in Ihrer Next.js-Anwendung zu erstellen. Dieser Leitfaden untersucht das Konzept der Route Handlers, ihre Vorteile und wie man sie effektiv einsetzt, um robuste APIs zu erstellen.

Was sind Next.js Route Handlers?

Route Handlers sind Funktionen, die im app-Verzeichnis eines Next.js-Projekts definiert sind und eingehende HTTP-Anfragen bearbeiten. Im Gegensatz zum älteren pages/api-Ansatz (der API-Routen verwendet) bieten Route Handlers eine optimiertere und flexiblere Möglichkeit, API-Endpunkte neben Ihren React-Komponenten zu definieren. Sie sind im Wesentlichen serverlose Funktionen, die am Edge oder in Ihrer gewählten Serverumgebung ausgeführt werden.

Stellen Sie sich Route Handlers als die Backend-Logik Ihrer Next.js-Anwendung vor, die für die Verarbeitung von Anfragen, die Interaktion mit Datenbanken und die Rückgabe von Antworten verantwortlich ist.

Vorteile der Verwendung von Route Handlers

Einrichten Ihres Next.js-Projekts

Bevor Sie sich mit Route Handlers befassen, stellen Sie sicher, dass Sie ein Next.js-Projekt mit dem app-Verzeichnis eingerichtet haben. Wenn Sie ein neues Projekt starten, verwenden Sie den folgenden Befehl:

npx create-next-app@latest my-nextjs-app

Wählen Sie während des Einrichtungsprozesses das app-Verzeichnis, um das neue Routing-System zu aktivieren.

Erstellen Ihres ersten Route Handlers

Lassen Sie uns einen einfachen API-Endpunkt erstellen, der eine JSON-Antwort zurückgibt. Erstellen Sie ein neues Verzeichnis im app-Verzeichnis, zum Beispiel /app/api/hello. Erstellen Sie in diesem Verzeichnis eine Datei namens route.ts (oder route.js, wenn Sie TypeScript nicht verwenden).

Hier ist der Code für Ihren ersten Route Handler:

// app/api/hello/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Hello from Next.js Route Handlers!' });
}

Erklärung:

Jetzt können Sie auf diesen Endpunkt zugreifen, indem Sie in Ihrem Browser zu /api/hello navigieren oder ein Tool wie curl oder Postman verwenden.

Umgang mit verschiedenen HTTP-Methoden

Route Handlers unterstützen verschiedene HTTP-Methoden wie GET, POST, PUT, DELETE, PATCH und OPTIONS. Sie können für jede Methode separate Funktionen in derselben route.ts-Datei definieren.

// app/api/users/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 // Logik zum Abrufen aller Benutzer aus der Datenbank
 const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // Beispieldaten
 return NextResponse.json(users);
}

export async function POST(request: Request) {
 const data = await request.json(); // Den Anfragekörper als JSON parsen
 // Logik zum Erstellen eines neuen Benutzers in der Datenbank mit 'data'
 const newUser = { id: 3, name: data.name, email: data.email }; // Beispiel
 return NextResponse.json(newUser, { status: 201 }); // Den neuen Benutzer mit dem Statuscode 201 Created zurückgeben
}

Erklärung:

Zugriff auf Anfragedaten

Das request-Objekt bietet Zugriff auf verschiedene Informationen über die eingehende Anfrage, einschließlich Header, Abfrageparameter und den Anfragekörper.

Headers

Sie können auf Anfrage-Header mit der Eigenschaft request.headers zugreifen:

export async function GET(request: Request) {
 const userAgent = request.headers.get('user-agent');
 console.log('User Agent:', userAgent);
 return NextResponse.json({ userAgent });
}

Abfrageparameter

Um auf Abfrageparameter zuzugreifen, können Sie den URL-Konstruktor verwenden:

export async function GET(request: Request) {
 const url = new URL(request.url);
 const searchParams = new URLSearchParams(url.search);
 const id = searchParams.get('id');
 console.log('ID:', id);
 return NextResponse.json({ id });
}

Anfragekörper (Request Body)

Bei POST-, PUT- und PATCH-Anfragen können Sie je nach Inhaltstyp mit den Methoden request.json() oder request.text() auf den Anfragekörper zugreifen.

export async function POST(request: Request) {
 const data = await request.json();
 console.log('Data:', data);
 return NextResponse.json({ receivedData: data });
}

Antworten zurückgeben

Das NextResponse-Objekt wird zum Erstellen von API-Antworten verwendet. Es bietet mehrere Methoden zum Festlegen von Headern, Statuscodes und Antwortkörpern.

JSON-Antworten

Verwenden Sie die Methode NextResponse.json(), um JSON-Antworten zurückzugeben:

return NextResponse.json({ message: 'Success!', data: { name: 'John Doe' } }, { status: 200 });

Text-Antworten

Verwenden Sie den Konstruktor new Response(), um einfache Text-Antworten zurückzugeben:

return new Response('Hello, world!', { status: 200, headers: { 'Content-Type': 'text/plain' } });

Weiterleitungen

Verwenden Sie NextResponse.redirect(), um Benutzer zu einer anderen URL weiterzuleiten:

import { redirect } from 'next/navigation';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.redirect(new URL('/new-location', request.url));
}

Header setzen

Sie können benutzerdefinierte Header mit der headers-Option in NextResponse.json() oder new Response() setzen:

return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });

Middleware-Integration

Middleware ermöglicht es Ihnen, Code auszuführen, bevor eine Anfrage von Ihrem Route Handler verarbeitet wird. Dies ist nützlich für Authentifizierung, Autorisierung, Protokollierung und andere übergreifende Belange.

Um eine Middleware zu erstellen, erstellen Sie eine Datei namens middleware.ts (oder middleware.js) im app-Verzeichnis oder einem beliebigen Unterverzeichnis. Die Middleware wird auf alle Routen in diesem Verzeichnis und seinen Unterverzeichnissen angewendet.

// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth-token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url));
 }

 return NextResponse.next();
}

export const config = {
 matcher: ['/protected/:path*'], // Diese Middleware auf Pfade anwenden, die mit /protected/ beginnen
};

Erklärung:

Fehlerbehandlung

Eine ordnungsgemäße Fehlerbehandlung ist für die Erstellung robuster APIs von entscheidender Bedeutung. Sie können try...catch-Blöcke verwenden, um Ausnahmen abzufangen und entsprechende Fehlerantworten zurückzugeben.

export async function GET(request: Request) {
 try {
 // Einen Fehler simulieren
 throw new Error('Something went wrong!');
 } catch (error: any) {
 console.error('Error:', error);
 return NextResponse.json({ error: error.message }, { status: 500 });
 }
}

Erklärung:

Streaming-Antworten

Route Handlers unterstützen Streaming-Antworten, wodurch Sie Daten schrittweise an den Client senden können. Dies ist besonders nützlich für große Datensätze oder lang andauernde Prozesse.

import { Readable } from 'stream';
import { NextResponse } from 'next/server';

async function* generateData() {
 for (let i = 0; i < 10; i++) {
 await new Promise(resolve => setTimeout(resolve, 500)); // Verzögerung simulieren
 yield `Data chunk ${i}\n`;
 }
}

export async function GET(request: Request) {
 const readableStream = Readable.from(generateData());

 return new Response(readableStream, {
 headers: { 'Content-Type': 'text/plain; charset=utf-8' },
 });
}

Erklärung:

Authentifizierung und Autorisierung

Die Sicherung Ihrer API-Endpunkte ist von entscheidender Bedeutung. Sie können Authentifizierung und Autorisierung mithilfe von Middleware oder direkt in Ihren Route Handlers implementieren.

Authentifizierung

Authentifizierung überprüft die Identität des Benutzers, der die Anfrage stellt. Gängige Authentifizierungsmethoden sind:

Hier ist ein Beispiel für die JWT-Authentifizierung mit Middleware:

// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import jwt from 'jsonwebtoken';

const secret = process.env.JWT_SECRET || 'your-secret-key'; // Ersetzen Sie dies durch ein starkes, zufällig generiertes Geheimnis

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth-token')?.value;

 if (!token) {
 return NextResponse.json({ message: 'Authentication required' }, { status: 401 });
 }

 try {
 jwt.verify(token, secret);
 return NextResponse.next();
 } catch (error) {
 return NextResponse.json({ message: 'Invalid token' }, { status: 401 });
 }
}

export const config = {
 matcher: ['/api/protected/:path*'],
};

Autorisierung

Autorisierung bestimmt, auf welche Ressourcen ein Benutzer zugreifen darf. Dies basiert typischerweise auf Rollen oder Berechtigungen.

Sie können die Autorisierung in Ihren Route Handlers implementieren, indem Sie die Rollen oder Berechtigungen des Benutzers überprüfen und einen Fehler zurückgeben, wenn er keinen Zugriff hat.

// app/api/admin/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 // Angenommen, Sie haben eine Funktion, um die Rolle des Benutzers aus dem Token oder der Sitzung zu erhalten
 const userRole = await getUserRole(request);

 if (userRole !== 'admin') {
 return NextResponse.json({ message: 'Unauthorized' }, { status: 403 });
 }

 // Logik zum Abrufen von Admin-Daten
 const adminData = { message: 'Admin data' };
 return NextResponse.json(adminData);
}

async function getUserRole(request: Request): Promise {
 // Ersetzen Sie dies durch Ihre tatsächliche Logik, um die Rolle des Benutzers aus der Anfrage zu extrahieren
 // Dies könnte die Überprüfung eines JWT-Tokens oder einer Sitzung beinhalten
 return 'admin'; // Beispiel: fest codierte Rolle zur Demonstration
}

Bereitstellen von Route Handlers

Route Handlers werden als serverlose Funktionen auf Ihrem gewählten Hosting-Anbieter bereitgestellt. Next.js unterstützt verschiedene Bereitstellungsplattformen, darunter Vercel, Netlify, AWS und mehr.

Für Vercel ist die Bereitstellung so einfach wie das Verbinden Ihres Git-Repositorys mit Vercel und das Pushen Ihres Codes. Vercel erkennt Ihr Next.js-Projekt automatisch und stellt Ihre Route Handlers als serverlose Funktionen bereit.

Fortgeschrittene Techniken

Edge Functions

Route Handlers können als Edge Functions bereitgestellt werden, die am Rande eines CDN, näher bei Ihren Benutzern, ausgeführt werden. Dies kann die Latenz erheblich reduzieren und die Leistung verbessern.

Um einen Route Handler als Edge Function bereitzustellen, fügen Sie die edge-Laufzeit zu Ihrer route.ts-Datei hinzu:

export const runtime = 'edge';

import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Hello from the Edge!' });
}

Server Actions

Server Actions ermöglichen es Ihnen, serverseitigen Code direkt aus Ihren React-Komponenten auszuführen. Route Handlers und Server Actions arbeiten nahtlos zusammen, sodass Sie komplexe Anwendungen mit Leichtigkeit erstellen können.

Hier ist ein Beispiel für die Verwendung einer Server Action, um einen Route Handler aufzurufen:

// app/components/MyComponent.tsx
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';

async function handleSubmit(data: FormData) {
 'use server';

 const name = data.get('name');
 const email = data.get('email');

 const response = await fetch('/api/users', {
 method: 'POST',
 body: JSON.stringify({ name, email }),
 });

 if (response.ok) {
 router.refresh(); // Die Seite aktualisieren, um die Änderungen zu übernehmen
 }
}

export default function MyComponent() {
 const router = useRouter();

 return (
 




); }

Caching

Caching kann die Leistung Ihrer API-Endpunkte erheblich verbessern. Sie können den Cache-Control-Header verwenden, um zu steuern, wie Ihre Antworten von Browsern und CDNs zwischengespeichert werden.

return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });

Dieses Beispiel setzt den Cache-Control-Header auf public, max-age=3600, was Browsern und CDNs anweist, die Antwort für eine Stunde zwischenzuspeichern.

Best Practices

Praxisbeispiele

Hier sind einige Praxisbeispiele, wie Route Handlers verwendet werden können:

Beispiel für internationalen E-Commerce: Ein Route Handler, der verwendet wird, um Produktpreise basierend auf dem Land des Benutzers abzurufen. Der Endpunkt könnte die Geolokalisierung der Anfrage (abgeleitet von der IP-Adresse) verwenden, um den Standort des Benutzers zu bestimmen und die Preise in der entsprechenden Währung zurückzugeben. Dies trägt zu einem lokalisierten Einkaufserlebnis bei.

Beispiel für globale Authentifizierung: Ein Route Handler, der eine Multi-Faktor-Authentifizierung (MFA) für Benutzer weltweit implementiert. Dies könnte das Senden von SMS-Codes oder die Verwendung von Authenticator-Apps umfassen, wobei die Datenschutzbestimmungen und Telekommunikationsinfrastrukturen der verschiedenen Regionen berücksichtigt werden.

Mehrsprachige Inhaltsauslieferung: Ein Route Handler, der Inhalte in der bevorzugten Sprache des Benutzers liefert. Dies kann aus dem `Accept-Language`-Header in der Anfrage ermittelt werden. Dieses Beispiel unterstreicht die Notwendigkeit einer korrekten UTF-8-Kodierung und gegebenenfalls der Unterstützung von Rechts-nach-Links-Sprachen.

Fazit

Next.js Route Handlers bieten eine leistungsstarke und flexible Möglichkeit, API-Endpunkte direkt in Ihrer Next.js-Anwendung zu erstellen. Durch die Nutzung von Route Handlers können Sie mühelos robuste APIs erstellen, Ihre Backend-Logik zusammen mit Ihren React-Komponenten platzieren und Funktionen wie Middleware, Streaming und Edge Functions nutzen.

Dieser umfassende Leitfaden hat alles von der Grundeinrichtung bis zu fortgeschrittenen Techniken abgedeckt. Indem Sie die in diesem Leitfaden beschriebenen Best Practices befolgen, können Sie qualitativ hochwertige APIs erstellen, die sicher, performant und wartbar sind.