API-маршруты в Next.js: создание и использование

Зачем использовать API в Next.js
Next.js — это мета‑фреймворк для React с набором функций, которые упрощают создание production‑готовых веб‑приложений. Один из удобных инструментов — file‑based API routing: вы пишете серверный код прямо в проекте, не создавая отдельного бекенда. Это ускоряет прототипирование и сокращает количество инфраструктуры для небольших и средних приложений.
Определение: API‑маршрут — это серверный обработчик, который принимает HTTP‑запросы и возвращает ответ (JSON, код ошибки и т.д.).
Создание проекта Next.js с помощью create-next-app
Вы можете создать новый проект Next.js с помощью CLI create-next-app — он установит все нужные пакеты и шаблон.
Запустите команду в терминале, чтобы создать папку проекта api-routes. Вам может прийти приглашение установить create-next-app.
`npx create-next-app api-routes
`
Когда команда завершит работу, откройте папку api-routes и приступайте к созданию API‑маршрутов.
Маршрутизация API в Next.js
API‑маршруты выполняются на сервере. Их можно использовать для сохранения данных в базе, проксирования запросов к внешним API без проблем с CORS или выполнения любой серверной логики.
Важно: все API‑маршруты должны находиться в папке /pages/api. Для каждого файла Next.js автоматически создаёт конечную точку API. Например, файл /pages/api/user.js станет доступен по адресу http://localhost:3000/api/user.
Простейший API‑обработчик выглядит так:
`export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
`
Экспорт функции обработчика обязателен для корректной работы.
Создаём маршрут API для todo
Добавьте файл todo.js в корень приложения (или в удобное место) для хранения тестовых данных, а далее создайте обработчик в /pages/api/todos.js.
Мокаем базу данных тасков
Для простоты мы используем массив объектов вместо реальной базы данных. Вы можете заменить его на MongoDB, MySQL или любую другую БД.
Добавьте данные todos в todo.js:
`export const todos = [
{
id: 1,
todo: "Do something nice for someone I care about",
completed: true,
userId: 26,
},
{
id: 2,
todo: "Memorize the fifty states and their capitals",
completed: false,
userId: 48,
},
// other todos
];
`
Эти примеры взяты из сервиса DummyJSON — REST API для мок‑данных.
Далее создайте /pages/api/todos.js с обработчиком:
`import { todos } from "../../todo";
export function handler(req, res) {
const { method } = req;
switch (method) {
case "GET":
res.status(200).json(todos);
break;
case "POST":
const { todo, completed } = req.body;
todos.push({
id: todos.length + 1,
todo,
completed,
});
res.status(200).json(todos);
break;
default:
res.setHeader("Allow", ["GET", "POST"]);
res.status(405).end(`Method ${method} Not Allowed`);
break;
}
}
`
Этот маршрут обрабатывает GET (возвращает все todos) и POST (добавляет новую задачу) запросы. Для остальных методов возвращается статус 405 и заголовок Allow.
Важно: такой подход с хранением в памяти подходит только для демо и тестов. В production используйте реальную базу и атомарные операции.
Как использовать API в интерфейсе (frontend)
После создания эндпоинта /api/todos вы можете обращаться к нему напрямую из компонентов Next.js, используя fetch или Axios.
Пример функции для получения todos и её вызов по клику:
`import Head from "next/head";
import { useState } from "react";
export default function Home() {
const [todos, settodos] = useState([]);
const fetchTodos = async () => {
const response = await fetch("/api/todos");
const data = await response.json();
settodos(data);
};
return (
Create Next App
{todos.map((todo) => {
return (
-
{todo.todo}:{todo.completed}.
);
})}
);
}
`
Этот компонент отображает список задач после нажатия кнопки.
Добавление задачи через POST
Функция saveTodo делает POST запрос и обновляет состояние todos согласно ответу API:
`const saveTodo = async () => {
const response = await fetch("/api/todos", {
method: "POST",
body: JSON.stringify(newTodo),
headers: {
"Content-Type": "application/json",
},
});
const data = await response.json();
settodos(data);
};
`
Форма с текстовым полем отправляет новый todo:
`import Head from "next/head";
import { useReducer, useState } from "react";
import styles from "../styles/Home.module.css";
export default function Home() {
const [todos, settodos] = useState([]);
const [newTodo, setnewTodo] = useState({
todo: "",
completed: false,
});
const fetchTodos = async () => {
// fetchTodos
};
const saveTodo = async (e) => {
const response = await fetch("/api/todos", {
method: "POST",
body: JSON.stringify(newTodo),
headers: {
"Content-Type": "application/json",
},
});
const data = await response.json();
settodos(data);
};
const handleChange = (e) => {
setnewTodo({
todo: e.target.value,
});
};
const handleSubmit = (e) => {
e.preventDefault();
saveTodo();
setnewTodo({
todo: '',
});
};
return (
Create Next App
// Fetches the todo items when clicked
// Saves a new todo item when submitted
{// list todo items}
);
}
`
Каждая отправка формы добавляет новый todo в «базу» и обновляет визуальный список.
Когда такой подход не подходит
- Для масштабируемых систем с высокой нагрузкой не стоит хранить данные в памяти: потеря процесса приведёт к потере данных.
- Если нужен сложный доступ ролей, транзакции, индексы и репликация — используйте полноценную БД и отдельный бекенд при необходимости.
- Для публичных API с высоким трафиком лучше выделить отдельный сервис и CDN.
Альтернативные подходы
- Использовать отдельный Node.js/Express‑сервис или серверless‑функции вне репозитория Next.js.
- Использовать API routes только как прокси к внешним микросервисам или BFF (Backend For Frontend).
- GraphQL вместо REST для более гибких запросов и типизации.
Руководство: минимальный рабочий процесс (mini‑methodology)
- Создайте проект: npx create-next-app.
- Добавьте структуру данных (или подключите БД).
- Создайте /pages/api/your-route.js и экспортируйте функцию-обработчик.
- Обрабатывайте методы по HTTP (GET, POST, PUT, DELETE) и возвращайте корректные коды статуса.
- На фронтенде используйте fetch/axios и обрабатывайте ошибки.
- Добавьте валидацию входных данных и проверки прав доступа.
- Тестируйте эндпоинты и добавьте мониторинг/логирование.
Контрольный список для ролей
Разработчик фронтенда:
- Проверил корректность URL /api/* и формата ответа JSON.
- Обработал статусы ошибок и показал пользователю понятные сообщения.
Разработчик бэкенда:
- Добавил обработку допустимых методов и заголовок Allow.
- Реализовал валидацию входных данных и защиту от инъекций.
DevOps/инфраструктура:
- Подготовил схему бэкапа для реальной базы данных.
- Настроил логирование и мониторинг latency/ошибок.
Безопасность и рекомендации по эксплуатации
- Валидация: всегда валидируйте тело запроса на сервере.
- Аутентификация: защищайте маршруты, где требуется доступ (JWT, session, middleware).
- Ограничение скорости: применяйте rate limiting для публичных эндпоинтов.
- Санитизация: не доверяйте данным из клиента (убирайте HTML/скрипты из пользовательского ввода).
- Не храните секреты в коде: используйте переменные окружения и секретные хранилища.
Критерии приёмки
- GET /api/todos возвращает массив задач и статус 200.
- POST /api/todos добавляет задачу при корректном теле и возвращает обновлённый массив.
- Для неподдерживаемого метода возвращается 405 и заголовок Allow с допустимыми методами.
- Клиент корректно отображает список и может добавлять новые задачи.
Ментальные модели и эвристики
- Разделение ответственности: UI отвечает за отображение/взаимодействие, API — за бизнес‑логику и консистентность данных.
- Принцип минимальной привилегии: давайте доступ только тем, кому он нужен.
- Стэйт на фронте — источник правды для отображения; источник правды для данных — БД/сервер.
Миграция на реальную базу: заметки
- Измените операции вставки/чтения в маршрутах на асинхронные обращения к БД.
- Для масштабирования используйте пул подключений и обработку ошибок повторными попытками.
- Учтите миграции схемы и обратную совместимость API.
Краткая справка (1‑строчный словарь)
- API route — серверная функция в файле /pages/api/*, которая отвечает на HTTP‑запросы.
Резюме
API‑маршрутизация в Next.js — быстрый способ добавить серверную логику в проект без отдельного сервера. Для прототипов и небольших приложений это удобный подход; для production‑систем с требованиями к надежности и масштабируемости потребуется полноценная база данных и дополнительные меры безопасности. Начните с простого примера todo, а затем постепенно вводите аутентификацию, валидацию и мониторинг.
Важно: сохраняйте данные в памяти только для тестов. Для продакшена — используйте БД и надёжные операции записи.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone