Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Обработчики маршрутов: свой API

Обработчик маршрута (route handler) — файл route.ts, который отвечает на HTTP-запросы данными, а не страницей. Так в Next.js делают API: для мобильного приложения, для чужих сайтов или для запросов из клиентских компонентов. Для форм на своём сайте обычно хватает серверных действий.

Первый обработчик

Создайте файл app/api/hello/route.ts:

// app/api/hello/route.ts
export async function GET() {
  return Response.json({ message: 'Привет из API' });
}

Имя экспортированной функции — HTTP-метод. Откройте http://localhost:3000/api/hello — браузер покажет {"message":"Привет из API"}. Объект Response — стандартный веб-API; метод Response.json превращает объект в JSON.

Данные комментариев

Комментарии будем хранить так же, как статьи, пока в памяти. Создайте lib/comments.ts:

// lib/comments.ts
export type Comment = { id: number; postSlug: string; author: string; text: string };
 
const comments: Comment[] = [
  { id: 1, postSlug: 'hello-nextjs', author: 'Олег', text: 'Отличная статья!' },
];
 
export async function getComments(postSlug: string): Promise<Comment[]> {
  return comments.filter((comment) => comment.postSlug === postSlug);
}
 
export async function addComment(postSlug: string, author: string, text: string): Promise<Comment> {
  const comment = { id: comments.length + 1, postSlug, author, text };
  comments.push(comment);
  return comment;
}

API комментариев

Обработчик для адреса /api/posts/hello-nextjs/comments лежит в папке с динамическим сегментом:

// app/api/posts/[slug]/comments/route.ts
import { addComment, getComments } from '@/lib/comments';
 
type Context = { params: Promise<{ slug: string }> };
 
export async function GET(request: Request, { params }: Context) {
  const { slug } = await params;
  return Response.json(await getComments(slug));
}
 
export async function POST(request: Request, { params }: Context) {
  const { slug } = await params;
  const data = await request.json();
 
  if (typeof data.text !== 'string' || data.text.trim() === '') {
    return Response.json({ error: 'Пустой комментарий' }, { status: 400 });
  }
 
  const comment = await addComment(slug, String(data.author ?? 'Гость'), data.text);
  return Response.json(comment, { status: 201 });
}

Параметры адреса приходят вторым аргументом, как у страниц, — промисом. Тело запроса читает request.json().

Проверка

curl http://localhost:3000/api/posts/hello-nextjs/comments
curl -X POST http://localhost:3000/api/posts/hello-nextjs/comments -H "Content-Type: application/json" -d "{\"author\":\"Anna\",\"text\":\"Thanks\"}"

Первая команда выведет массив с комментарием Олега, вторая добавит новый и вернёт его со статусом 201. Повторный GET покажет оба.

Что ещё доступно

ЗадачаКак
Параметры ?page=2new URL(request.url).searchParams.get('page')
Заголовкиrequest.headers.get('authorization')
Другие методыФункции PUT, PATCH, DELETE

В Next.js 16 обработчики GET по умолчанию не кешируются и выполняются на каждый запрос (если не включены Cache Components).

Частая ошибка

Положить route.ts и page.tsx в одну папку, например в app/posts. Один адрес не может быть и страницей, и API — Next.js сообщит о конфликте. Держите API в отдельной папке app/api/.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.