Naučte se vytvářet výkonné API endpointy pomocí Next.js Route Handlers. Tento průvodce pokrývá vše od základního nastavení po pokročilé techniky, s praktickými příklady a osvědčenými postupy.
Next.js Route Handlers: Komplexní průvodce tvorbou API endpointů
Next.js způsobil revoluci ve způsobu, jakým tvoříme webové aplikace, díky svým výkonným funkcím, jako je server-side rendering, generování statických stránek a nyní Route Handlers. Route Handlers poskytují flexibilní a efektivní způsob, jak vytvářet API endpointy přímo ve vaší Next.js aplikaci. Tento průvodce prozkoumává koncept Route Handlers, jejich výhody a jak je efektivně používat k budování robustních API.
Co jsou Next.js Route Handlers?
Route Handlers jsou funkce definované v adresáři app
projektu Next.js, které zpracovávají příchozí HTTP požadavky. Na rozdíl od staršího přístupu pages/api
(který používá API Routes) nabízejí Route Handlers efektivnější a flexibilnější způsob definování API endpointů vedle vašich React komponent. Jsou to v podstatě serverless funkce spouštěné na edge nebo ve vámi zvoleném serverovém prostředí.
Představte si Route Handlers jako backendovou logiku vaší Next.js aplikace, která je zodpovědná za zpracování požadavků, interakci s databázemi a vracení odpovědí.
Výhody používání Route Handlers
- Kolokace: Route Handlers se nacházejí přímo vedle vašich React komponent v adresáři
app
, což podporuje lepší organizaci a udržovatelnost kódu. - Podpora TypeScriptu: Vestavěná podpora TypeScriptu zajišťuje typovou bezpečnost a lepší vývojářský zážitek.
- Integrace Middleware: Snadno integrujte middleware pro úkoly jako autentizace, autorizace a validace požadavků.
- Podpora streamování: Route Handlers mohou streamovat data, což vám umožňuje posílat odpovědi postupně, což je výhodné pro velké datové sady nebo dlouhotrvající procesy.
- Edge Functions: Nasaďte Route Handlers jako Edge Functions pro odpovědi s nízkou latencí blíže vašim uživatelům, s využitím globálních CDN.
- Zjednodušený návrh API: Route Handlers poskytují čisté a intuitivní API pro zpracování požadavků a odpovědí.
- Integrace se Server Actions: Úzká integrace se Server Actions umožňuje bezproblémovou komunikaci mezi vašimi komponentami na straně klienta a logikou na straně serveru.
Nastavení vašeho Next.js projektu
Než se ponoříte do Route Handlers, ujistěte se, že máte nastavený projekt Next.js s adresářem app
. Pokud zakládáte nový projekt, použijte následující příkaz:
npx create-next-app@latest my-nextjs-app
Během procesu nastavení zvolte adresář app
, abyste povolili nový systém směrování.
Vytvoření vašeho prvního Route Handleru
Vytvořme jednoduchý API endpoint, který vrací JSON odpověď. Vytvořte nový adresář v adresáři app
, například /app/api/hello
. Uvnitř tohoto adresáře vytvořte soubor s názvem route.ts
(nebo route.js
, pokud nepoužíváte TypeScript).
Zde je kód vašeho prvního Route Handleru:
// 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!' });
}
Vysvětlení:
import { NextResponse } from 'next/server';
: Importuje objektNextResponse
, který se používá k vytváření API odpovědí.export async function GET(request: Request) { ... }
: Definuje asynchronní funkci, která zpracovává GET požadavky na endpoint/api/hello
. Parametrrequest
poskytuje přístup k objektu příchozího požadavku.return NextResponse.json({ message: 'Hello from Next.js Route Handlers!' });
: Vytvoří JSON odpověď se zprávou a vrátí ji pomocíNextResponse.json()
.
Nyní můžete k tomuto endpointu přistupovat přechodem na /api/hello
ve vašem prohlížeči nebo pomocí nástroje jako curl
nebo Postman
.
Zpracování různých HTTP metod
Route Handlers podporují různé HTTP metody jako GET, POST, PUT, DELETE, PATCH a OPTIONS. Můžete definovat samostatné funkce pro každou metodu ve stejném souboru route.ts
.
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Logika pro získání všech uživatelů z databáze
const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // Příklad dat
return NextResponse.json(users);
}
export async function POST(request: Request) {
const data = await request.json(); // Zpracování těla požadavku jako JSON
// Logika pro vytvoření nového uživatele v databázi pomocí 'data'
const newUser = { id: 3, name: data.name, email: data.email }; // Příklad
return NextResponse.json(newUser, { status: 201 }); // Vrácení nového uživatele se stavovým kódem 201 Created
}
Vysvětlení:
- Funkce
GET
získá seznam uživatelů (zde simulovaný) a vrátí je jako JSON odpověď. - Funkce
POST
zpracuje tělo požadavku jako JSON, vytvoří nového uživatele (simulovaně) a vrátí nového uživatele se stavovým kódem 201 Created.
Přístup k datům požadavku
Objekt request
poskytuje přístup k různým informacím o příchozím požadavku, včetně hlaviček, parametrů dotazu a těla požadavku.
Hlavičky (Headers)
K hlavičkám požadavku můžete přistupovat pomocí vlastnosti request.headers
:
export async function GET(request: Request) {
const userAgent = request.headers.get('user-agent');
console.log('User Agent:', userAgent);
return NextResponse.json({ userAgent });
}
Parametry dotazu (Query Parameters)
Pro přístup k parametrům dotazu můžete použít konstruktor URL
:
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 });
}
Tělo požadavku (Request Body)
U požadavků POST, PUT a PATCH můžete přistupovat k tělu požadavku pomocí metod request.json()
nebo request.text()
, v závislosti na typu obsahu.
export async function POST(request: Request) {
const data = await request.json();
console.log('Data:', data);
return NextResponse.json({ receivedData: data });
}
Vracení odpovědí
Objekt NextResponse
se používá k vytváření API odpovědí. Poskytuje několik metod pro nastavení hlaviček, stavových kódů a těl odpovědí.
JSON odpovědi
Pro vrácení JSON odpovědí použijte metodu NextResponse.json()
:
return NextResponse.json({ message: 'Success!', data: { name: 'John Doe' } }, { status: 200 });
Textové odpovědi
Pro vrácení čistě textových odpovědí použijte konstruktor new Response()
:
return new Response('Hello, world!', { status: 200, headers: { 'Content-Type': 'text/plain' } });
Přesměrování (Redirects)
Pro přesměrování uživatelů na jinou URL použijte NextResponse.redirect()
:
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));
}
Nastavení hlaviček (Headers)
Můžete nastavit vlastní hlavičky pomocí volby headers
v NextResponse.json()
nebo new Response()
:
return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });
Integrace Middleware
Middleware umožňuje spustit kód předtím, než je požadavek zpracován vaším Route Handlerem. To je užitečné pro autentizaci, autorizaci, logování a další průřezové záležitosti.
Pro vytvoření middleware vytvořte soubor s názvem middleware.ts
(nebo middleware.js
) v adresáři app
nebo v jakémkoli podadresáři. Middleware se bude vztahovat na všechny trasy v tomto adresáři a jeho podadresářích.
// 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*'], // Aplikovat tento middleware na cesty začínající /protected/
};
Vysvětlení:
- Funkce
middleware
kontroluje přítomnost autentizačního tokenu v cookies požadavku. - Pokud token chybí, přesměruje uživatele na přihlašovací stránku.
- V opačném případě umožní požadavku pokračovat do Route Handleru.
- Objekt
config
specifikuje, že tento middleware by se měl aplikovat pouze na trasy začínající/protected/
.
Zpracování chyb
Správné zpracování chyb je klíčové pro budování robustních API. Můžete použít bloky try...catch
k zachycení výjimek a vrácení příslušných chybových odpovědí.
export async function GET(request: Request) {
try {
// Simulace chyby
throw new Error('Something went wrong!');
} catch (error: any) {
console.error('Error:', error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
}
Vysvětlení:
- Blok
try...catch
zachytí jakékoli výjimky, které nastanou v rámci Route Handleru. - V bloku
catch
je chyba zaznamenána a je vrácena chybová odpověď se stavovým kódem 500 Internal Server Error.
Streamování odpovědí
Route Handlers podporují streamování odpovědí, což vám umožňuje posílat data klientovi postupně. To je zvláště užitečné pro velké datové sady nebo dlouhotrvající procesy.
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)); // Simulace zpoždění
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' },
});
}
Vysvětlení:
- Funkce
generateData
je asynchronní generátor, který poskytuje datové bloky se zpožděním. - Metoda
Readable.from()
vytváří čitelný stream z generátoru. - Objekt
Response
je vytvořen s čitelným streamem jako tělem a hlavičkaContent-Type
je nastavena natext/plain
.
Autentizace a autorizace
Zabezpečení vašich API endpointů je klíčové. Můžete implementovat autentizaci a autorizaci pomocí middleware nebo přímo ve vašich Route Handlerech.
Autentizace
Autentizace ověřuje identitu uživatele, který provádí požadavek. Běžné metody autentizace zahrnují:
- JWT (JSON Web Tokens): Vygenerujte token po úspěšném přihlášení a ověřte jej při následných požadavcích.
- Autentizace založená na session: Použijte cookies k uložení identifikátorů session a ověřujte je při každém požadavku.
- OAuth: Delegujte autentizaci na poskytovatele třetí strany, jako je Google nebo Facebook.
Zde je příklad JWT autentizace pomocí 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'; // Nahraďte silným, náhodně generovaným tajemstvím
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*'],
};
Autorizace
Autorizace určuje, ke kterým zdrojům má uživatel povolen přístup. To je obvykle založeno na rolích nebo oprávněních.
Autorizaci můžete implementovat ve svých Route Handlerech kontrolou rolí nebo oprávnění uživatele a vrácením chyby, pokud nemá přístup.
// app/api/admin/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Předpokládejme, že máte funkci pro získání role uživatele z tokenu nebo session
const userRole = await getUserRole(request);
if (userRole !== 'admin') {
return NextResponse.json({ message: 'Unauthorized' }, { status: 403 });
}
// Logika pro získání dat pro administrátory
const adminData = { message: 'Admin data' };
return NextResponse.json(adminData);
}
async function getUserRole(request: Request): Promise {
// Nahraďte vaší skutečnou logikou pro extrakci role uživatele z požadavku
// To může zahrnovat ověření JWT tokenu nebo kontrolu session
return 'admin'; // Příklad: natvrdo zakódovaná role pro demonstraci
}
Nasazení Route Handlers
Route Handlers jsou nasazovány jako serverless funkce na vámi zvoleném hostingovém poskytovateli. Next.js podporuje různé platformy pro nasazení, včetně Vercel, Netlify, AWS a dalších.
Pro Vercel je nasazení jednoduché jako připojení vašeho Git repozitáře k Vercelu a nahrání kódu. Vercel automaticky detekuje váš Next.js projekt a nasadí vaše Route Handlers jako serverless funkce.
Pokročilé techniky
Edge Functions
Route Handlers mohou být nasazeny jako Edge Functions, které jsou spouštěny na okraji CDN, blíže k vašim uživatelům. To může výrazně snížit latenci a zlepšit výkon.
Pro nasazení Route Handleru jako Edge Function přidejte runtime edge
do vašeho souboru route.ts
:
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 vám umožňují spouštět kód na straně serveru přímo z vašich React komponent. Route Handlers a Server Actions spolu bezproblémově spolupracují, což vám umožňuje snadno vytvářet komplexní aplikace.
Zde je příklad použití Server Action k volání Route Handleru:
// 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(); // Obnovení stránky, aby se projevily změny
}
}
export default function MyComponent() {
const router = useRouter();
return (
);
}
Caching (ukládání do mezipaměti)
Caching může výrazně zlepšit výkon vašich API endpointů. Můžete použít hlavičku Cache-Control
k řízení toho, jak jsou vaše odpovědi ukládány do mezipaměti prohlížeči a CDN.
return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });
Tento příklad nastavuje hlavičku Cache-Control
na public, max-age=3600
, což říká prohlížečům a CDN, aby odpověď ukládaly do mezipaměti po dobu jedné hodiny.
Osvědčené postupy (Best Practices)
- Používejte TypeScript: Využijte typové bezpečnosti TypeScriptu ke zlepšení kvality kódu a předcházení chybám.
- Validujte požadavky: Validujte příchozí požadavky, abyste zajistili integritu dat a zabránili škodlivému vstupu.
- Zpracovávejte chyby elegantně: Implementujte správné zpracování chyb, abyste klientům poskytli informativní chybové zprávy.
- Zabezpečte své endpointy: Implementujte autentizaci a autorizaci k ochraně vašich API endpointů.
- Používejte Middleware: Používejte middleware pro průřezové záležitosti, jako je autentizace, logování a validace požadavků.
- Ukládejte odpovědi do mezipaměti: Používejte caching ke zlepšení výkonu vašich API endpointů.
- Monitorujte svá API: Monitorujte svá API, abyste rychle identifikovali a řešili problémy.
- Dokumentujte svá API: Dokumentujte svá API, aby je ostatní vývojáři mohli snadno používat. Zvažte použití nástrojů jako Swagger/OpenAPI pro dokumentaci API.
Příklady z reálného světa
Zde je několik příkladů z reálného světa, jak lze Route Handlers použít:
- E-commerce API: Vytvořte API endpointy pro správu produktů, objednávek a uživatelů.
- API pro sociální média: Vytvořte API endpointy pro zveřejňování tweetů, sledování uživatelů a získávání časových os.
- API pro systém správy obsahu (CMS): Vytvořte API endpointy pro správu obsahu, uživatelů a nastavení.
- API pro analýzu dat: Vytvořte API endpointy pro sběr a analýzu dat. Například Route Handler by mohl přijímat data ze sledovacích pixelů na různých webových stránkách a agregovat informace pro reportování.
Příklad mezinárodního e-commerce: Route Handler použitý k získání cen produktů na základě země uživatele. Endpoint by mohl použít geolokaci požadavku (odvozenou z IP adresy) k určení polohy uživatele a vrátit ceny v příslušné měně. To přispívá k lokalizovanému nákupnímu zážitku.
Příklad globální autentizace: Route Handler implementující vícefaktorovou autentizaci (MFA) pro uživatele po celém světě. To by mohlo zahrnovat odesílání SMS kódů nebo používání autentizačních aplikací, při respektování předpisů o ochraně soukromí a telekomunikačních infrastruktur různých regionů.
Doručování vícejazyčného obsahu: Route Handler doručující obsah v preferovaném jazyce uživatele. To lze určit z hlavičky `Accept-Language` v požadavku. Tento příklad zdůrazňuje potřebu správného kódování UTF-8 a podpory jazyků psaných zprava doleva, kde je to vhodné.
Závěr
Next.js Route Handlers poskytují výkonný a flexibilní způsob, jak vytvářet API endpointy přímo ve vaší Next.js aplikaci. Využitím Route Handlers můžete snadno vytvářet robustní API, umisťovat vaši backendovou logiku vedle vašich React komponent a využívat funkce jako middleware, streamování a Edge Functions.
Tento komplexní průvodce pokryl vše od základního nastavení po pokročilé techniky. Dodržováním osvědčených postupů uvedených v tomto průvodci můžete vytvářet vysoce kvalitní API, která jsou bezpečná, výkonná a udržovatelná.