Română

Învățați cum să creați endpoint-uri API puternice folosind Route Handlers în Next.js. Acest ghid acoperă totul, de la configurarea de bază la tehnici avansate, cu exemple practice și cele mai bune practici.

Route Handlers în Next.js: Un Ghid Complet pentru Crearea de Endpoint-uri API

Next.js a revoluționat modul în care construim aplicații web cu funcționalitățile sale puternice precum randarea pe server (server-side rendering), generarea de site-uri statice (static site generation) și, acum, Route Handlers. Route Handlers oferă o modalitate flexibilă și eficientă de a crea endpoint-uri API direct în aplicația dvs. Next.js. Acest ghid explorează conceptul de Route Handlers, beneficiile acestora și cum să le utilizați eficient pentru a construi API-uri robuste.

Ce sunt Route Handlers în Next.js?

Route Handlers sunt funcții definite în directorul app al unui proiect Next.js care gestionează cererile HTTP primite. Spre deosebire de abordarea mai veche pages/api (care utilizează API Routes), Route Handlers oferă o modalitate mai simplificată și flexibilă de a defini endpoint-uri API alături de componentele dvs. React. Acestea sunt în esență funcții serverless executate la edge sau în mediul de server ales de dvs.

Gândiți-vă la Route Handlers ca la logica de backend a aplicației dvs. Next.js, responsabilă pentru procesarea cererilor, interacțiunea cu bazele de date și returnarea răspunsurilor.

Beneficiile Utilizării Route Handlers

Configurarea Proiectului Dvs. Next.js

Înainte de a explora Route Handlers, asigurați-vă că aveți un proiect Next.js configurat cu directorul app. Dacă începeți un proiect nou, utilizați următoarea comandă:

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

Alegeți directorul app în timpul procesului de configurare pentru a activa noul sistem de rutare.

Crearea Primului Dvs. Route Handler

Să creăm un endpoint API simplu care returnează un răspuns JSON. Creați un nou director în interiorul directorului app, de exemplu, /app/api/hello. În acest director, creați un fișier numit route.ts (sau route.js dacă nu utilizați TypeScript).

Iată codul pentru primul dvs. Route Handler:

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

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

Explicație:

Acum, puteți accesa acest endpoint navigând la /api/hello în browserul dvs. sau folosind un instrument precum curl sau Postman.

Gestionarea Diferitelor Metode HTTP

Route Handlers suportă diverse metode HTTP precum GET, POST, PUT, DELETE, PATCH și OPTIONS. Puteți defini funcții separate pentru fiecare metodă în același fișier route.ts.

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

export async function GET(request: Request) {
 // Logică pentru a prelua toți utilizatorii din baza de date
 const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // Date exemplu
 return NextResponse.json(users);
}

export async function POST(request: Request) {
 const data = await request.json(); // Parsează corpul cererii ca JSON
 // Logică pentru a crea un utilizator nou în baza de date folosind 'data'
 const newUser = { id: 3, name: data.name, email: data.email }; // Exemplu
 return NextResponse.json(newUser, { status: 201 }); // Returnează utilizatorul nou cu un cod de stare 201 Created
}

Explicație:

Accesarea Datelor din Cerere

Obiectul request oferă acces la diverse informații despre cererea primită, inclusiv antete, parametrii interogării și corpul cererii.

Antete (Headers)

Puteți accesa antetele cererii folosind proprietatea request.headers:

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

Parametrii Interogării (Query Parameters)

Pentru a accesa parametrii interogării, puteți utiliza constructorul 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 });
}

Corpul Cererii (Request Body)

Pentru cererile POST, PUT și PATCH, puteți accesa corpul cererii folosind metodele request.json() sau request.text(), în funcție de tipul de conținut.

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

Returnarea Răspunsurilor

Obiectul NextResponse este utilizat pentru a construi răspunsuri API. Acesta oferă mai multe metode pentru setarea antetelor, codurilor de stare și corpurilor de răspuns.

Răspunsuri JSON

Utilizați metoda NextResponse.json() pentru a returna răspunsuri JSON:

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

Răspunsuri Text

Utilizați constructorul new Response() pentru a returna răspunsuri text simplu:

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

Redirecționări

Utilizați NextResponse.redirect() pentru a redirecționa utilizatorii către o altă adresă 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));
}

Setarea Antetelor (Headers)

Puteți seta antete personalizate folosind opțiunea headers în NextResponse.json() sau new Response():

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

Integrarea Middleware

Middleware-ul vă permite să rulați cod înainte ca o cerere să fie gestionată de Route Handler-ul dvs. Acest lucru este util pentru autentificare, autorizare, logging și alte preocupări transversale.

Pentru a crea un middleware, creați un fișier numit middleware.ts (sau middleware.js) în directorul app sau în orice subdirector. Middleware-ul se va aplica tuturor rutelor din acel director și subdirectoarele sale.

// 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*'], // Aplică acest middleware pe căile care încep cu /protected/
};

Explicație:

Gestionarea Erorilor

Gestionarea corectă a erorilor este crucială pentru construirea de API-uri robuste. Puteți utiliza blocuri try...catch pentru a gestiona excepțiile și a returna răspunsuri de eroare corespunzătoare.

export async function GET(request: Request) {
 try {
 // Simulează o eroare
 throw new Error('Ceva nu a mers bine!');
 } catch (error: any) {
 console.error('Eroare:', error);
 return NextResponse.json({ error: error.message }, { status: 500 });
 }
}

Explicație:

Răspunsuri în Flux (Streaming)

Route Handlers suportă răspunsuri în flux (streaming), ceea ce vă permite să trimiteți date incremental către client. Acest lucru este deosebit de util pentru seturi mari de date sau procese de lungă durată.

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)); // Simulează o întârziere
 yield `Bucată de date ${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' },
 });
}

Explicație:

Autentificare și Autorizare

Securizarea endpoint-urilor API este crucială. Puteți implementa autentificarea și autorizarea folosind middleware sau direct în cadrul Route Handlers.

Autentificare

Autentificarea verifică identitatea utilizatorului care face cererea. Metodele comune de autentificare includ:

Iată un exemplu de autentificare JWT folosind 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'; // Înlocuiți cu un secret puternic, generat aleatoriu

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

 if (!token) {
 return NextResponse.json({ message: 'Autentificare necesară' }, { status: 401 });
 }

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

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

Autorizare

Autorizarea determină la ce resurse are acces un utilizator. Aceasta se bazează de obicei pe roluri sau permisiuni.

Puteți implementa autorizarea în cadrul Route Handlers prin verificarea rolurilor sau permisiunilor utilizatorului și returnarea unei erori dacă acesta nu are acces.

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

export async function GET(request: Request) {
 // Presupunem că aveți o funcție pentru a obține rolul utilizatorului din token sau sesiune
 const userRole = await getUserRole(request);

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

 // Logică pentru a prelua date de administrator
 const adminData = { message: 'Date de administrator' };
 return NextResponse.json(adminData);
}

async function getUserRole(request: Request): Promise {
 // Înlocuiți cu logica dvs. reală pentru a extrage rolul utilizatorului din cerere
 // Aceasta ar putea implica verificarea unui token JWT sau verificarea unei sesiuni
 return 'admin'; // Exemplu: rol codat direct pentru demonstrație
}

Implementarea (Deploying) Route Handlers

Route Handlers sunt implementate ca funcții serverless pe furnizorul dvs. de găzduire ales. Next.js suportă diverse platforme de implementare, inclusiv Vercel, Netlify, AWS și altele.

Pentru Vercel, implementarea este la fel de simplă ca și conectarea depozitului Git la Vercel și trimiterea codului. Vercel detectează automat proiectul dvs. Next.js și implementează Route Handlers ca funcții serverless.

Tehnici Avansate

Funcții Edge

Route Handlers pot fi implementate ca Funcții Edge (Edge Functions), care sunt executate la marginea unei rețele CDN, mai aproape de utilizatorii dvs. Acest lucru poate reduce semnificativ latența și îmbunătăți performanța.

Pentru a implementa un Route Handler ca Funcție Edge, adăugați runtime-ul edge în fișierul dvs. route.ts:

export const runtime = 'edge';

import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Salut de la Edge!' });
}

Acțiuni Server (Server Actions)

Acțiunile Server (Server Actions) vă permit să executați cod server-side direct din componentele dvs. React. Route Handlers și Server Actions funcționează perfect împreună, permițându-vă să construiți aplicații complexe cu ușurință.

Iată un exemplu de utilizare a unei Acțiuni Server pentru a apela un 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(); // Reîmprospătează pagina pentru a reflecta schimbările
 }
}

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

 return (
 




); }

Caching (Memorare în Cache)

Memorarea în cache (caching) poate îmbunătăți semnificativ performanța endpoint-urilor API. Puteți utiliza antetul Cache-Control pentru a controla modul în care răspunsurile dvs. sunt memorate în cache de către browsere și CDN-uri.

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

Acest exemplu setează antetul Cache-Control la public, max-age=3600, ceea ce indică browserelor și CDN-urilor să memoreze în cache răspunsul timp de o oră.

Cele Mai Bune Practici

Exemple din Lumea Reală

Iată câteva exemple din lumea reală despre cum pot fi utilizate Route Handlers:

Exemplu de E-commerce Internațional: Un Route Handler folosit pentru a prelua prețurile produselor în funcție de țara utilizatorului. Endpoint-ul ar putea folosi geolocația cererii (derivată din adresa IP) pentru a determina locația utilizatorului și a returna prețuri în moneda corespunzătoare. Acest lucru contribuie la o experiență de cumpărături localizată.

Exemplu de Autentificare Globală: Un Route Handler care implementează autentificarea multi-factor (MFA) pentru utilizatori din întreaga lume. Acest lucru ar putea implica trimiterea de coduri SMS sau utilizarea de aplicații de autentificare, respectând în același timp reglementările privind confidențialitatea și infrastructurile de telecomunicații din diferite regiuni.

Livrarea de Conținut Multilingv: Un Route Handler care livrează conținut în limba preferată a utilizatorului. Aceasta poate fi determinată din antetul `Accept-Language` din cerere. Acest exemplu evidențiază necesitatea unei codificări UTF-8 corespunzătoare și a suportului pentru limbi de la dreapta la stânga, acolo unde este cazul.

Concluzie

Route Handlers din Next.js oferă o modalitate puternică și flexibilă de a crea endpoint-uri API direct în aplicația dvs. Next.js. Prin utilizarea Route Handlers, puteți construi API-uri robuste cu ușurință, puteți colocaliza logica de backend cu componentele React și puteți profita de funcționalități precum middleware, streaming și Funcții Edge.

Acest ghid cuprinzător a acoperit totul, de la configurarea de bază la tehnici avansate. Urmând cele mai bune practici prezentate în acest ghid, puteți construi API-uri de înaltă calitate, care sunt sigure, performante și ușor de întreținut.