Български

Научете как да създавате мощни API крайни точки с Next.js Route Handlers. Ръководството обхваща всичко от основна настройка до напреднали техники, с практически примери и добри практики.

Next.js Route Handlers: Цялостно ръководство за създаване на API крайни точки

Next.js направи революция в начина, по който изграждаме уеб приложения със своите мощни функции като рендиране от страна на сървъра, генериране на статични сайтове и сега, Route Handlers. Route Handlers предоставят гъвкав и ефективен начин за създаване на API крайни точки директно във вашето Next.js приложение. Това ръководство изследва концепцията на Route Handlers, техните предимства и как ефективно да ги използвате за изграждане на стабилни API-та.

Какво представляват Next.js Route Handlers?

Route Handlers са функции, дефинирани в директорията app на Next.js проект, които обработват входящи HTTP заявки. За разлика от по-стария подход с pages/api (който използва API Routes), Route Handlers предлагат по-оптимизиран и гъвкав начин за дефиниране на API крайни точки заедно с вашите React компоненти. Те по същество са сървърлес функции, изпълнявани на edge или във вашата избрана сървърна среда.

Мислете за Route Handlers като за бекенд логиката на вашето Next.js приложение, отговорна за обработката на заявки, взаимодействието с бази данни и връщането на отговори.

Предимства на използването на Route Handlers

Настройка на вашия Next.js проект

Преди да се потопите в Route Handlers, уверете се, че имате настроен Next.js проект с директорията app. Ако започвате нов проект, използвайте следната команда:

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

Изберете директорията app по време на процеса на настройка, за да активирате новата система за маршрутизация.

Създаване на първия ви Route Handler

Нека създадем проста API крайна точка, която връща JSON отговор. Създайте нова директория в директорията app, например /app/api/hello. Вътре в тази директория създайте файл с име route.ts (или route.js, ако не използвате TypeScript).

Ето кода за вашия първи Route Handler:

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

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Здравейте от Next.js Route Handlers!' });
}

Обяснение:

Сега можете да получите достъп до тази крайна точка, като отидете на /api/hello във вашия браузър или използвате инструмент като curl или Postman.

Обработка на различни HTTP методи

Route Handlers поддържат различни HTTP методи като GET, POST, PUT, DELETE, PATCH и OPTIONS. Можете да дефинирате отделни функции за всеки метод в рамките на един и същ файл route.ts.

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

export async function GET(request: Request) {
 // Логика за извличане на всички потребители от базата данни
 const users = [{ id: 1, name: 'Иван Петров' }, { id: 2, name: 'Мария Иванова' }]; // Примерни данни
 return NextResponse.json(users);
}

export async function POST(request: Request) {
 const data = await request.json(); // Парсване на тялото на заявката като JSON
 // Логика за създаване на нов потребител в базата данни, използвайки 'data'
 const newUser = { id: 3, name: data.name, email: data.email }; // Пример
 return NextResponse.json(newUser, { status: 201 }); // Връщане на новия потребител със статус код 201 Created
}

Обяснение:

Достъп до данните от заявката

Обектът request предоставя достъп до различна информация за входящата заявка, включително хедъри, параметри на заявката (query parameters) и тялото на заявката.

Хедъри (Headers)

Можете да получите достъп до хедърите на заявката, като използвате свойството 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 Parameters)

За достъп до параметрите на заявката можете да използвате конструктора 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 });
}

Тяло на заявката (Request Body)

За POST, PUT и PATCH заявки можете да получите достъп до тялото на заявката, като използвате методите request.json() или request.text(), в зависимост от типа на съдържанието.

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

Връщане на отговори

Обектът NextResponse се използва за конструиране на API отговори. Той предоставя няколко метода за задаване на хедъри, статус кодове и тела на отговорите.

JSON отговори

Използвайте метода NextResponse.json(), за да върнете JSON отговори:

return NextResponse.json({ message: 'Успех!', data: { name: 'Иван Петров' } }, { status: 200 });

Текстови отговори

Използвайте конструктора new Response(), за да върнете обикновени текстови отговори:

return new Response('Здравей, свят!', { status: 200, headers: { 'Content-Type': 'text/plain' } });

Пренасочвания (Redirects)

Използвайте NextResponse.redirect(), за да пренасочите потребителите към друг 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));
}

Задаване на хедъри

Можете да зададете персонализирани хедъри, като използвате опцията headers в NextResponse.json() или new Response():

return NextResponse.json({ message: 'Успех!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });

Интеграция на Middleware

Middleware ви позволява да изпълнявате код преди заявката да бъде обработена от вашия Route Handler. Това е полезно за автентикация, оторизация, логване и други свързани задачи.

За да създадете middleware, създайте файл с име middleware.ts (или middleware.js) в директорията app или в някоя нейна поддиректория. Middleware ще се прилага за всички маршрути в тази директория и нейните поддиректории.

// 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*'], // Приложи този middleware към пътища, започващи с /protected/
};

Обяснение:

Обработка на грешки

Правилната обработка на грешки е от решаващо значение за изграждането на стабилни API-та. Можете да използвате блокове try...catch, за да обработвате изключения и да връщате подходящи отговори за грешки.

export async function GET(request: Request) {
 try {
 // Симулиране на грешка
 throw new Error('Нещо се обърка!');
 } catch (error: any) {
 console.error('Грешка:', error);
 return NextResponse.json({ error: error.message }, { status: 500 });
 }
}

Обяснение:

Поточни отговори (Streaming Responses)

Route Handlers поддържат поточни отговори, което ви позволява да изпращате данни инкрементално към клиента. Това е особено полезно за големи набори от данни или дълготрайни процеси.

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)); // Симулиране на забавяне
 yield `Част от данни ${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' },
 });
}

Обяснение:

Автентикация и оторизация

Защитата на вашите API крайни точки е от решаващо значение. Можете да внедрите автентикация и оторизация, като използвате middleware или директно във вашите Route Handlers.

Автентикация

Автентикацията проверява самоличността на потребителя, който прави заявката. Често срещаните методи за автентикация включват:

Ето пример за JWT автентикация с помощта на 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'; // Заменете със силен, произволно генериран таен ключ

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

 if (!token) {
 return NextResponse.json({ message: 'Необходима е автентикация' }, { status: 401 });
 }

 try {
 jwt.verify(token, secret);
 return NextResponse.next();
 } catch (error) {
 return NextResponse.json({ message: 'Невалиден токен' }, { status: 401 });
 }
}

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

Оторизация

Оторизацията определя до какви ресурси има достъп даден потребител. Това обикновено се основава на роли или разрешения.

Можете да внедрите оторизация във вашите Route Handlers, като проверявате ролите или разрешенията на потребителя и връщате грешка, ако те нямат достъп.

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

export async function GET(request: Request) {
 // Да приемем, че имате функция за получаване на ролята на потребителя от токена или сесията
 const userRole = await getUserRole(request);

 if (userRole !== 'admin') {
 return NextResponse.json({ message: 'Неоторизиран достъп' }, { status: 403 });
 }

 // Логика за извличане на администраторски данни
 const adminData = { message: 'Администраторски данни' };
 return NextResponse.json(adminData);
}

async function getUserRole(request: Request): Promise {
 // Заменете с вашата реална логика за извличане на ролята на потребителя от заявката
 // Това може да включва проверка на JWT токен или проверка на сесия
 return 'admin'; // Пример: твърдо кодирана роля за демонстрация
}

Внедряване на Route Handlers

Route Handlers се внедряват като сървърлес функции на избрания от вас хостинг доставчик. Next.js поддържа различни платформи за внедряване, включително Vercel, Netlify, AWS и други.

За Vercel внедряването е толкова просто, колкото свързването на вашето Git хранилище с Vercel и пушването на вашия код. Vercel автоматично открива вашия Next.js проект и внедрява вашите Route Handlers като сървърлес функции.

Напреднали техники

Edge функции

Route Handlers могат да бъдат внедрени като Edge функции, които се изпълняват на ръба (edge) на CDN мрежа, по-близо до вашите потребители. Това може значително да намали латентността и да подобри производителността.

За да внедрите Route Handler като Edge функция, добавете edge runtime към вашия файл route.ts:

export const runtime = 'edge';

import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Здравейте от Edge!' });
}

Сървърни действия (Server Actions)

Сървърните действия ви позволяват да изпълнявате код от страна на сървъра директно от вашите React компоненти. Route Handlers и Server Actions работят безпроблемно заедно, което ви позволява лесно да изграждате сложни приложения.

Ето пример за използване на Server Action за извикване на 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(); // Опресняване на страницата, за да се отразят промените
 }
}

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

 return (
 




); }

Кеширане

Кеширането може значително да подобри производителността на вашите API крайни точки. Можете да използвате хедъра Cache-Control, за да контролирате как вашите отговори се кешират от браузърите и CDN мрежите.

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

Този пример задава хедъра Cache-Control на public, max-age=3600, което казва на браузърите и CDN мрежите да кешират отговора за един час.

Добри практики

Примери от реалния свят

Ето няколко примера от реалния свят за това как могат да се използват Route Handlers:

Пример за международна електронна търговия: Route Handler, използван за извличане на цени на продукти въз основа на държавата на потребителя. Крайната точка може да използва геолокацията на заявката (получена от IP адреса), за да определи местоположението на потребителя и да върне цени в съответната валута. Това допринася за локализирано пазаруване.

Пример за глобална автентикация: Route Handler, който внедрява многофакторна автентикация (MFA) за потребители по целия свят. Това може да включва изпращане на SMS кодове или използване на приложения за автентикация, като същевременно се спазват регулациите за поверителност и телекомуникационните инфраструктури на различните региони.

Многоезично доставяне на съдържание: Route Handler, който доставя съдържание на предпочитания от потребителя език. Това може да се определи от хедъра `Accept-Language` в заявката. Този пример подчертава необходимостта от правилно кодиране в UTF-8 и поддръжка на езици, които се пишат отдясно наляво, когато е уместно.

Заключение

Next.js Route Handlers предоставят мощен и гъвкав начин за създаване на API крайни точки директно във вашето Next.js приложение. Като използвате Route Handlers, можете лесно да изграждате стабилни API-та, да разполагате вашата бекенд логика заедно с вашите React компоненти и да се възползвате от функции като middleware, стрийминг и Edge функции.

Това цялостно ръководство обхвана всичко от основна настройка до напреднали техники. Като следвате добрите практики, очертани в това ръководство, можете да изграждате висококачествени API-та, които са сигурни, производителни и лесни за поддръжка.

Next.js Route Handlers: Цялостно ръководство за създаване на API крайни точки | MLOG