Lär dig skapa kraftfulla API-endpoints med Next.js Route Handlers. Guiden täcker allt från grundläggande konfiguration till avancerade tekniker, med praktiska exempel.
Next.js Route Handlers: En Omfattande Guide till att Skapa API-Endpoints
Next.js har revolutionerat sättet vi bygger webbapplikationer på med sina kraftfulla funktioner som server-side rendering, static site generation och nu, Route Handlers. Route Handlers erbjuder ett flexibelt och effektivt sätt att skapa API-endpoints direkt i din Next.js-applikation. Denna guide utforskar konceptet med Route Handlers, deras fördelar och hur man effektivt använder dem för att bygga robusta API:er.
Vad är Next.js Route Handlers?
Route Handlers är funktioner som definieras i app
-katalogen i ett Next.js-projekt och hanterar inkommande HTTP-förfrågningar. Till skillnad från det äldre pages/api
-tillvägagångssättet (som använder API Routes), erbjuder Route Handlers ett mer strömlinjeformat och flexibelt sätt att definiera API-endpoints vid sidan av dina React-komponenter. De är i grunden serverlösa funktioner som körs på edge-nätverket eller i din valda servermiljö.
Tänk på Route Handlers som backend-logiken i din Next.js-applikation, ansvarig för att bearbeta förfrågningar, interagera med databaser och returnera svar.
Fördelar med att Använda Route Handlers
- Samlokalisering: Route Handlers ligger direkt bredvid dina React-komponenter i
app
-katalogen, vilket främjar bättre organisation och kodunderhåll. - TypeScript-stöd: Inbyggt TypeScript-stöd säkerställer typsäkerhet och en förbättrad utvecklarupplevelse.
- Middleware-integration: Integrera enkelt middleware för uppgifter som autentisering, auktorisering och validering av förfrågningar.
- Stöd för streaming: Route Handlers kan strömma data, vilket gör att du kan skicka svar inkrementellt, vilket är fördelaktigt för stora datamängder eller långvariga processer.
- Edge Functions: Driftsätt Route Handlers som Edge Functions för låg latens och svar närmare dina användare, med hjälp av globala CDN:er.
- Förenklad API-design: Route Handlers erbjuder ett rent och intuitivt API för att hantera förfrågningar och svar.
- Integration med Server Actions: Tätt integration med Server Actions möjliggör sömlös kommunikation mellan dina klientkomponenter och serverlogik.
Konfigurera ditt Next.js-projekt
Innan du dyker in i Route Handlers, se till att du har ett Next.js-projekt konfigurerat med app
-katalogen. Om du startar ett nytt projekt, använd följande kommando:
npx create-next-app@latest my-nextjs-app
Välj app
-katalogen under installationsprocessen för att aktivera det nya routingsystemet.
Skapa din Första Route Handler
Låt oss skapa en enkel API-endpoint som returnerar ett JSON-svar. Skapa en ny katalog i app
-katalogen, till exempel /app/api/hello
. Inuti denna katalog, skapa en fil med namnet route.ts
(eller route.js
om du inte använder TypeScript).
Här är koden för din första Route Handler:
// app/api/hello/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.json({ message: 'Hej från Next.js Route Handlers!' });
}
Förklaring:
import { NextResponse } from 'next/server';
: ImporterarNextResponse
-objektet, som används för att konstruera API-svar.export async function GET(request: Request) { ... }
: Definierar en asynkron funktion som hanterar GET-förfrågningar till/api/hello
-endpointen.request
-parametern ger tillgång till det inkommande förfrågningsobjektet.return NextResponse.json({ message: 'Hello from Next.js Route Handlers!' });
: Skapar ett JSON-svar med ett meddelande och returnerar det medNextResponse.json()
.
Nu kan du komma åt denna endpoint genom att navigera till /api/hello
i din webbläsare eller använda ett verktyg som curl
eller Postman
.
Hantera Olika HTTP-metoder
Route Handlers stöder olika HTTP-metoder som GET, POST, PUT, DELETE, PATCH och OPTIONS. Du kan definiera separata funktioner för varje metod i samma route.ts
-fil.
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Logik för att hämta alla användare från databasen
const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // Exempeldata
return NextResponse.json(users);
}
export async function POST(request: Request) {
const data = await request.json(); // Tolka förfrågningens body som JSON
// Logik för att skapa en ny användare i databasen med 'data'
const newUser = { id: 3, name: data.name, email: data.email }; // Exempel
return NextResponse.json(newUser, { status: 201 }); // Returnera den nya användaren med statuskod 201 Created
}
Förklaring:
GET
-funktionen hämtar en lista över användare (simulerat här) och returnerar dem som ett JSON-svar.POST
-funktionen tolkar förfrågningens body som JSON, skapar en ny användare (simulerat) och returnerar den nya användaren med statuskoden 201 Created.
Åtkomst till Förfrågningsdata
request
-objektet ger tillgång till diverse information om den inkommande förfrågningen, inklusive headers, query-parametrar och förfrågningens body.
Headers
Du kan komma åt request-headers med egenskapen request.headers
:
export async function GET(request: Request) {
const userAgent = request.headers.get('user-agent');
console.log('User Agent:', userAgent);
return NextResponse.json({ userAgent });
}
Query-parametrar
För att komma åt query-parametrar kan du använda URL
-konstruktorn:
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 });
}
Request Body
För POST-, PUT- och PATCH-förfrågningar kan du komma åt förfrågningens body med metoderna request.json()
eller request.text()
, beroende på innehållstyp.
export async function POST(request: Request) {
const data = await request.json();
console.log('Data:', data);
return NextResponse.json({ receivedData: data });
}
Returnera Svar
NextResponse
-objektet används för att konstruera API-svar. Det tillhandahåller flera metoder för att ställa in headers, statuskoder och svarskroppar (response bodies).
JSON-svar
Använd metoden NextResponse.json()
för att returnera JSON-svar:
return NextResponse.json({ message: 'Lyckades!', data: { name: 'John Doe' } }, { status: 200 });
Text-svar
Använd konstruktorn new Response()
för att returnera rena text-svar:
return new Response('Hej, världen!', { status: 200, headers: { 'Content-Type': 'text/plain' } });
Omdirigeringar
Använd NextResponse.redirect()
för att omdirigera användare till en annan URL:
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));
}
Ställa in Headers
Du kan ställa in anpassade headers med alternativet headers
i NextResponse.json()
eller new Response()
:
return NextResponse.json({ message: 'Lyckades!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });
Middleware-integration
Middleware låter dig köra kod innan en förfrågan hanteras av din Route Handler. Detta är användbart för autentisering, auktorisering, loggning och andra övergripande aspekter (cross-cutting concerns).
För att skapa middleware, skapa en fil med namnet middleware.ts
(eller middleware.js
) i app
-katalogen eller en underkatalog. Middleware-funktionen kommer att gälla för alla rutter inom den katalogen och dess underkataloger.
// 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*'], // Tillämpa denna middleware på sökvägar som börjar med /protected/
};
Förklaring:
middleware
-funktionen kontrollerar om det finns en autentiseringstoken i förfrågningens cookies.- Om token saknas omdirigerar den användaren till inloggningssidan.
- Annars tillåter den förfrågan att fortsätta till Route Handler.
config
-objektet specificerar att denna middleware endast ska gälla för rutter som börjar med/protected/
.
Felhantering
Korrekt felhantering är avgörande för att bygga robusta API:er. Du kan använda try...catch
-block för att hantera undantag och returnera lämpliga felsvar.
export async function GET(request: Request) {
try {
// Simulera ett fel
throw new Error('Något gick fel!');
} catch (error: any) {
console.error('Fel:', error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
}
Förklaring:
try...catch
-blocket fångar alla undantag som inträffar inom Route Handler.- I
catch
-blocket loggas felet, och ett felsvar returneras med statuskoden 500 Internal Server Error.
Strömmande Svar (Streaming)
Route Handlers stöder strömmande svar, vilket låter dig skicka data inkrementellt till klienten. Detta är särskilt användbart för stora datamängder eller långvariga processer.
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)); // Simulera fördröjning
yield `Datadel ${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' },
});
}
Förklaring:
- Funktionen
generateData
är en asynkron generator som producerar datadelar (yields) med en fördröjning. - Metoden
Readable.from()
skapar en läsbar ström (readable stream) från generatorn. Response
-objektet skapas med den läsbara strömmen som body, ochContent-Type
-headern sätts tilltext/plain
.
Autentisering och Auktorisering
Att säkra dina API-endpoints är avgörande. Du kan implementera autentisering och auktorisering med hjälp av middleware eller direkt i dina Route Handlers.
Autentisering
Autentisering verifierar identiteten hos användaren som gör förfrågan. Vanliga autentiseringsmetoder inkluderar:
- JWT (JSON Web Tokens): Generera en token vid lyckad inloggning och verifiera den vid efterföljande förfrågningar.
- Sessionsbaserad autentisering: Använd cookies för att lagra sessionsidentifierare och verifiera dem vid varje förfrågan.
- OAuth: Delegera autentisering till en tredjepartsleverantör som Google eller Facebook.
Här är ett exempel på JWT-autentisering med 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 || 'din-hemliga-nyckel'; // Ersätt med ett starkt, slumpmässigt genererat hemligt nyckelord
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value;
if (!token) {
return NextResponse.json({ message: 'Autentisering krävs' }, { status: 401 });
}
try {
jwt.verify(token, secret);
return NextResponse.next();
} catch (error) {
return NextResponse.json({ message: 'Ogiltig token' }, { status: 401 });
}
}
export const config = {
matcher: ['/api/protected/:path*'],
};
Auktorisering
Auktorisering bestämmer vilka resurser en användare har tillgång till. Detta baseras vanligtvis på roller eller behörigheter.
Du kan implementera auktorisering inom dina Route Handlers genom att kontrollera användarens roller eller behörigheter och returnera ett fel om de inte har tillgång.
// app/api/admin/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Anta att du har en funktion för att hämta användarens roll från token eller session
const userRole = await getUserRole(request);
if (userRole !== 'admin') {
return NextResponse.json({ message: 'Obehörig' }, { status: 403 });
}
// Logik för att hämta admindata
const adminData = { message: 'Admindata' };
return NextResponse.json(adminData);
}
async function getUserRole(request: Request): Promise {
// Ersätt med din faktiska logik för att extrahera användarens roll från förfrågan
// Detta kan innebära att verifiera en JWT-token eller kontrollera en session
return 'admin'; // Exempel: hårdkodad roll för demonstration
}
Driftsättning av Route Handlers
Route Handlers driftsätts som serverlösa funktioner på din valda hosting-leverantör. Next.js stöder olika driftsättningsplattformar, inklusive Vercel, Netlify, AWS och fler.
För Vercel är driftsättning så enkelt som att ansluta ditt Git-repository till Vercel och pusha din kod. Vercel upptäcker automatiskt ditt Next.js-projekt och driftsätter dina Route Handlers som serverlösa funktioner.
Avancerade Tekniker
Edge Functions
Route Handlers kan driftsättas som Edge Functions, som körs på kanten av ett CDN, närmare dina användare. Detta kan avsevärt minska latens och förbättra prestandan.
För att driftsätta en Route Handler som en Edge Function, lägg till edge
runtime i din route.ts
-fil:
export const runtime = 'edge';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.json({ message: 'Hej från Edge!' });
}
Server Actions
Server Actions låter dig köra server-side-kod direkt från dina React-komponenter. Route Handlers och Server Actions fungerar sömlöst tillsammans, vilket gör att du enkelt kan bygga komplexa applikationer.
Här är ett exempel på hur man använder en Server Action för att anropa en Route Handler:
// 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(); // Uppdatera sidan för att visa ändringarna
}
}
export default function MyComponent() {
const router = useRouter();
return (
);
}
Cachelagring
Cachelagring kan avsevärt förbättra prestandan för dina API-endpoints. Du kan använda Cache-Control
-headern för att styra hur dina svar cachelagras av webbläsare och CDN:er.
return NextResponse.json({ message: 'Lyckades!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });
Detta exempel sätter Cache-Control
-headern till public, max-age=3600
, vilket talar om för webbläsare och CDN:er att cachelagra svaret i en timme.
Bästa Praxis
- Använd TypeScript: Dra nytta av TypeScripts typsäkerhet för att förbättra kodkvaliteten och förhindra fel.
- Validera förfrågningar: Validera inkommande förfrågningar för att säkerställa dataintegritet och förhindra skadlig indata.
- Hantera fel elegant: Implementera korrekt felhantering för att ge informativa felmeddelanden till klienter.
- Säkra dina endpoints: Implementera autentisering och auktorisering för att skydda dina API-endpoints.
- Använd middleware: Använd middleware för övergripande aspekter som autentisering, loggning och validering av förfrågningar.
- Cachelagra svar: Använd cachelagring för att förbättra prestandan för dina API-endpoints.
- Övervaka dina API:er: Övervaka dina API:er för att snabbt identifiera och lösa problem.
- Dokumentera dina API:er: Dokumentera dina API:er för att göra dem enkla att använda för andra utvecklare. Överväg att använda verktyg som Swagger/OpenAPI för API-dokumentation.
Verkliga Exempel
Här är några verkliga exempel på hur Route Handlers kan användas:
- E-handels-API: Skapa API-endpoints för att hantera produkter, ordrar och användare.
- Sociala medier-API: Skapa API-endpoints för att publicera inlägg, följa användare och hämta tidslinjer.
- API för innehållshanteringssystem (CMS): Skapa API-endpoints för att hantera innehåll, användare och inställningar.
- Dataanalys-API: Skapa API-endpoints för att samla in och analysera data. Till exempel kan en Route Handler ta emot data från spårningspixlar på olika webbplatser och aggregera informationen för rapportering.
Exempel med internationell e-handel: En Route Handler som används för att hämta produktpriser baserat på användarens land. Endpointen kan använda förfrågningens geolokalisering (härledd från IP-adress) för att bestämma användarens plats och returnera priser i lämplig valuta. Detta bidrar till en lokaliserad shoppingupplevelse.
Exempel med global autentisering: En Route Handler som implementerar multifaktorautentisering (MFA) för användare världen över. Detta kan innebära att skicka SMS-koder eller använda autentiseringsappar, med respekt för olika regioners integritetslagstiftning och telekommunikationsinfrastrukturer.
Leverans av flerspråkigt innehåll: En Route Handler som levererar innehåll på användarens föredragna språk. Detta kan bestämmas från Accept-Language
-headern i förfrågan. Detta exempel belyser behovet av korrekt UTF-8-kodning och stöd för språk som skrivs från höger till vänster där det är lämpligt.
Sammanfattning
Next.js Route Handlers erbjuder ett kraftfullt och flexibelt sätt att skapa API-endpoints direkt i din Next.js-applikation. Genom att utnyttja Route Handlers kan du enkelt bygga robusta API:er, samlokalisera din backend-logik med dina React-komponenter och dra nytta av funktioner som middleware, streaming och Edge Functions.
Denna omfattande guide har täckt allt från grundläggande konfiguration till avancerade tekniker. Genom att följa de bästa praxis som beskrivs i denna guide kan du bygga högkvalitativa API:er som är säkra, presterande och underhållbara.