Lær hvordan du lager kraftige API-endepunkter med Next.js Route Handlers. Denne guiden dekker alt fra grunnleggende oppsett til avanserte teknikker, med praktiske eksempler og beste praksis.
Next.js Route Handlers: En Omfattende Guide til Opprettelse av API-endepunkter
Next.js har revolusjonert måten vi bygger webapplikasjoner på med sine kraftige funksjoner som server-side rendering, statisk sidegenerering, og nå, Route Handlers. Route Handlers gir en fleksibel og effektiv måte å lage API-endepunkter direkte i din Next.js-applikasjon. Denne guiden utforsker konseptet med Route Handlers, deres fordeler, og hvordan man effektivt bruker dem til å bygge robuste API-er.
Hva er Next.js Route Handlers?
Route Handlers er funksjoner definert i app
-katalogen i et Next.js-prosjekt som håndterer innkommende HTTP-forespørsler. I motsetning til den eldre pages/api
-tilnærmingen (som bruker API Routes), tilbyr Route Handlers en mer strømlinjeformet og fleksibel måte å definere API-endepunkter ved siden av dine React-komponenter. De er i hovedsak serverløse funksjoner som kjøres på edge-nettverket eller i ditt valgte servermiljø.
Tenk på Route Handlers som backend-logikken i din Next.js-applikasjon, ansvarlig for å behandle forespørsler, samhandle med databaser og returnere responser.
Fordeler med å Bruke Route Handlers
- Samlokalisering: Route Handlers ligger direkte ved siden av dine React-komponenter i
app
-katalogen, noe som fremmer bedre organisering og vedlikehold av koden. - TypeScript-støtte: Innebygd TypeScript-støtte sikrer typesikkerhet og en forbedret utvikleropplevelse.
- Middleware-integrasjon: Integrer enkelt mellomvare (middleware) for oppgaver som autentisering, autorisasjon og validering av forespørsler.
- Strømmestøtte: Route Handlers kan strømme data, noe som gjør at du kan sende responser inkrementelt. Dette er fordelaktig for store datasett eller langvarige prosesser.
- Edge-funksjoner: Deployer Route Handlers som Edge-funksjoner for lav latenstid og responser nærmere brukerne dine, ved å utnytte globale CDN-er.
- Forenklet API-design: Route Handlers gir et rent og intuitivt API for håndtering av forespørsler og responser.
- Integrasjon med Server Actions: Tett integrasjon med Server Actions tillater sømløs kommunikasjon mellom dine klient-side-komponenter og server-side-logikk.
Sette Opp Ditt Next.js-prosjekt
Før du dykker inn i Route Handlers, sørg for at du har et Next.js-prosjekt satt opp med app
-katalogen. Hvis du starter et nytt prosjekt, bruk følgende kommando:
npx create-next-app@latest my-nextjs-app
Velg app
-katalogen under oppsettsprosessen for å aktivere det nye rutesystemet.
Opprette din Første Route Handler
La oss lage et enkelt API-endepunkt som returnerer en JSON-respons. Opprett en ny katalog i app
-katalogen, for eksempel /app/api/hello
. Inne i denne katalogen, opprett en fil med navnet route.ts
(eller route.js
hvis du ikke bruker TypeScript).
Her er koden for din første 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!' });
}
Forklaring:
import { NextResponse } from 'next/server';
: ImportererNextResponse
-objektet, som brukes til å konstruere API-responser.export async function GET(request: Request) { ... }
: Definerer en asynkron funksjon som håndterer GET-forespørsler til/api/hello
-endepunktet.request
-parameteren gir tilgang til det innkommende forespørselsobjektet.return NextResponse.json({ message: 'Hello from Next.js Route Handlers!' });
: Oppretter en JSON-respons med en melding og returnerer den ved hjelp avNextResponse.json()
.
Nå kan du få tilgang til dette endepunktet ved å navigere til /api/hello
i nettleseren din eller ved å bruke et verktøy som curl
eller Postman
.
Håndtering av Forskjellige HTTP-metoder
Route Handlers støtter ulike HTTP-metoder som GET, POST, PUT, DELETE, PATCH og OPTIONS. Du kan definere separate funksjoner for hver metode i den samme route.ts
-filen.
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Logikk for å hente alle brukere fra databasen
const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // Eksempeldata
return NextResponse.json(users);
}
export async function POST(request: Request) {
const data = await request.json(); // Parse forespørselskroppen som JSON
// Logikk for å opprette en ny bruker i databasen med 'data'
const newUser = { id: 3, name: data.name, email: data.email }; // Eksempel
return NextResponse.json(newUser, { status: 201 }); // Returner den nye brukeren med statuskoden 201 Created
}
Forklaring:
GET
-funksjonen henter en liste over brukere (simulert her) og returnerer dem som en JSON-respons.POST
-funksjonen parser forespørselskroppen som JSON, oppretter en ny bruker (simulert), og returnerer den nye brukeren med statuskoden 201 Created.
Tilgang til Forespørselsdata
request
-objektet gir tilgang til diverse informasjon om den innkommende forespørselen, inkludert headere, spørringsparametere og forespørselskroppen.
Headere
Du kan få tilgang til forespørselsheadere ved hjelp av request.headers
-egenskapen:
export async function GET(request: Request) {
const userAgent = request.headers.get('user-agent');
console.log('User Agent:', userAgent);
return NextResponse.json({ userAgent });
}
Spørringsparametere
For å få tilgang til spørringsparametere kan du bruke URL
-konstruktøren:
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 });
}
Forespørselskropp
For POST-, PUT- og PATCH-forespørsler kan du få tilgang til forespørselskroppen ved å bruke metodene request.json()
eller request.text()
, avhengig av innholdstypen.
export async function POST(request: Request) {
const data = await request.json();
console.log('Data:', data);
return NextResponse.json({ receivedData: data });
}
Returnere Responser
NextResponse
-objektet brukes til å konstruere API-responser. Det gir flere metoder for å sette headere, statuskoder og responskropper.
JSON-responser
Bruk NextResponse.json()
-metoden for å returnere JSON-responser:
return NextResponse.json({ message: 'Success!', data: { name: 'John Doe' } }, { status: 200 });
Tekstresponser
Bruk new Response()
-konstruktøren for å returnere rene tekstresponser:
return new Response('Hello, world!', { status: 200, headers: { 'Content-Type': 'text/plain' } });
Omdirigeringer
Bruk NextResponse.redirect()
for å omdirigere brukere til en annen 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));
}
Sette Headere
Du kan sette egendefinerte headere ved å bruke headers
-alternativet i NextResponse.json()
eller new Response()
:
return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });
Middleware-integrasjon
Middleware lar deg kjøre kode før en forespørsel håndteres av din Route Handler. Dette er nyttig for autentisering, autorisasjon, logging og andre tverrgående bekymringer.
For å lage middleware, opprett en fil med navnet middleware.ts
(eller middleware.js
) i app
-katalogen eller en hvilken som helst underkatalog. Mellomvaren vil gjelde for alle ruter i den katalogen og dens 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*'], // Bruk denne mellomvaren for stier som starter med /protected/
};
Forklaring:
middleware
-funksjonen sjekker for et autentiseringstoken i forespørselens informasjonskapsler (cookies).- Hvis tokenet mangler, omdirigerer den brukeren til innloggingssiden.
- Ellers lar den forespørselen fortsette til Route Handler.
config
-objektet spesifiserer at denne mellomvaren kun skal gjelde for ruter som starter med/protected/
.
Feilhåndtering
Riktig feilhåndtering er avgjørende for å bygge robuste API-er. Du kan bruke try...catch
-blokker for å håndtere unntak og returnere passende feilresponser.
export async function GET(request: Request) {
try {
// Simuler en feil
throw new Error('Something went wrong!');
} catch (error: any) {
console.error('Error:', error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
}
Forklaring:
try...catch
-blokken fanger opp eventuelle unntak som oppstår i Route Handler.- I
catch
-blokken blir feilen logget, og en feilrespons returneres med statuskoden 500 Internal Server Error.
Strømming av Responser
Route Handlers støtter strømming av responser, noe som lar deg sende data inkrementelt til klienten. Dette er spesielt nyttig for store datasett eller langvarige prosesser.
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)); // Simuler forsinkelse
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' },
});
}
Forklaring:
generateData
-funksjonen er en asynkron generator som yielder databiter med en forsinkelse.Readable.from()
-metoden lager en lesbar strøm fra generatoren.Response
-objektet opprettes med den lesbare strømmen som kropp, ogContent-Type
-headeren er satt tiltext/plain
.
Autentisering og Autorisasjon
Å sikre API-endepunktene dine er avgjørende. Du kan implementere autentisering og autorisasjon ved hjelp av middleware eller direkte i dine Route Handlers.
Autentisering
Autentisering verifiserer identiteten til brukeren som sender forespørselen. Vanlige autentiseringsmetoder inkluderer:
- JWT (JSON Web Tokens): Generer et token ved vellykket innlogging og verifiser det påfølgende forespørsler.
- Sesjonsbasert autentisering: Bruk informasjonskapsler (cookies) til å lagre sesjonsidentifikatorer og verifiser dem på hver forespørsel.
- OAuth: Deleger autentisering til en tredjepartsleverandør som Google eller Facebook.
Her er et eksempel på JWT-autentisering ved hjelp av 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'; // Erstatt med en sterk, tilfeldig generert hemmelighet
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*'],
};
Autorisasjon
Autorisasjon bestemmer hvilke ressurser en bruker har tilgang til. Dette er vanligvis basert på roller eller tillatelser.
Du kan implementere autorisasjon i dine Route Handlers ved å sjekke brukerens roller eller tillatelser og returnere en feil hvis de ikke har tilgang.
// app/api/admin/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Anta at du har en funksjon for å hente brukerens rolle fra tokenet eller sesjonen
const userRole = await getUserRole(request);
if (userRole !== 'admin') {
return NextResponse.json({ message: 'Unauthorized' }, { status: 403 });
}
// Logikk for å hente admin-data
const adminData = { message: 'Admin data' };
return NextResponse.json(adminData);
}
async function getUserRole(request: Request): Promise {
// Erstatt med din faktiske logikk for å trekke ut brukerens rolle fra forespørselen
// Dette kan innebære å verifisere et JWT-token eller sjekke en sesjon
return 'admin'; // Eksempel: hardkodet rolle for demonstrasjon
}
Deploye Route Handlers
Route Handlers blir deployet som serverløse funksjoner på din valgte vertsleverandør. Next.js støtter ulike deployeringsplattformer, inkludert Vercel, Netlify, AWS og flere.
For Vercel er deployering så enkelt som å koble ditt Git-repository til Vercel og pushe koden din. Vercel oppdager automatisk ditt Next.js-prosjekt og deployer dine Route Handlers som serverløse funksjoner.
Avanserte Teknikker
Edge-funksjoner
Route Handlers kan deployes som Edge-funksjoner, som kjøres på kanten av et CDN, nærmere brukerne dine. Dette kan redusere ventetiden betydelig og forbedre ytelsen.
For å deploye en Route Handler som en Edge-funksjon, legg til 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: 'Hello from the Edge!' });
}
Server Actions
Server Actions lar deg kjøre server-side-kode direkte fra dine React-komponenter. Route Handlers og Server Actions fungerer sømløst sammen, slik at du kan bygge komplekse applikasjoner med letthet.
Her er et eksempel på hvordan du bruker en Server Action til å kalle 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(); // Oppdater siden for å gjenspeile endringene
}
}
export default function MyComponent() {
const router = useRouter();
return (
);
}
Mellomlagring (Caching)
Mellomlagring (caching) kan forbedre ytelsen til API-endepunktene dine betydelig. Du kan bruke Cache-Control
-headeren til å kontrollere hvordan responsene dine mellomlagres av nettlesere og CDN-er.
return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });
Dette eksemplet setter Cache-Control
-headeren til public, max-age=3600
, som forteller nettlesere og CDN-er at de skal mellomlagre responsen i én time.
Beste Praksis
- Bruk TypeScript: Utnytt TypeScript sin typesikkerhet for å forbedre kodekvaliteten og forhindre feil.
- Valider Forespørsler: Valider innkommende forespørsler for å sikre dataintegritet og forhindre ondsinnet input.
- Håndter Feil Elegant: Implementer skikkelig feilhåndtering for å gi informative feilmeldinger til klienter.
- Sikre Endepunktene Dine: Implementer autentisering og autorisasjon for å beskytte API-endepunktene dine.
- Bruk Middleware: Bruk middleware for tverrgående bekymringer som autentisering, logging og validering av forespørsler.
- Mellomlagre Responser: Bruk mellomlagring for å forbedre ytelsen til API-endepunktene dine.
- Overvåk API-ene Dine: Overvåk API-ene dine for å identifisere og løse problemer raskt.
- Dokumenter API-ene Dine: Dokumenter API-ene dine for å gjøre dem enkle å bruke for andre utviklere. Vurder å bruke verktøy som Swagger/OpenAPI for API-dokumentasjon.
Eksempler fra Virkeligheten
Her er noen eksempler fra den virkelige verden på hvordan Route Handlers kan brukes:
- E-handels-API: Lag API-endepunkter for å administrere produkter, bestillinger og brukere.
- Sosiale Medier-API: Lag API-endepunkter for å publisere tweets, følge brukere og hente tidslinjer.
- Content Management System (CMS) API: Lag API-endepunkter for å administrere innhold, brukere og innstillinger.
- Dataanalyse-API: Lag API-endepunkter for å samle inn og analysere data. For eksempel kan en Route Handler motta data fra sporingspiksler på forskjellige nettsteder og aggregere informasjonen for rapportering.
Eksempel på internasjonal e-handel: En Route Handler brukt for å hente produktpriser basert på brukerens land. Endepunktet kan bruke forespørselens geolokasjon (avledet fra IP-adresse) for å bestemme brukerens plassering og returnere priser i riktig valuta. Dette bidrar til en lokalisert handleopplevelse.
Eksempel på global autentisering: En Route Handler som implementerer multifaktorautentisering (MFA) for brukere over hele verden. Dette kan innebære å sende SMS-koder eller bruke autentiseringsapper, samtidig som man respekterer personvernregler og telekommunikasjonsinfrastruktur i ulike regioner.
Levering av flerspråklig innhold: En Route Handler som leverer innhold på brukerens foretrukne språk. Dette kan bestemmes fra Accept-Language
-headeren i forespørselen. Dette eksemplet fremhever behovet for korrekt UTF-8-koding og støtte for språk som leses fra høyre til venstre der det er aktuelt.
Konklusjon
Next.js Route Handlers gir en kraftig og fleksibel måte å lage API-endepunkter direkte i din Next.js-applikasjon. Ved å utnytte Route Handlers kan du enkelt bygge robuste API-er, samlokalisere backend-logikken din med React-komponentene dine, og dra nytte av funksjoner som middleware, strømming og Edge-funksjoner.
Denne omfattende guiden har dekket alt fra grunnleggende oppsett til avanserte teknikker. Ved å følge beste praksis som er skissert i denne guiden, kan du bygge høykvalitets API-er som er sikre, ytelsesdyktige og vedlikeholdbare.