Маршруты API
Примеры
Важно знать: Если вы используете App Router, вы можете использовать Компоненты сервера или Обработчики маршрутов вместо маршрутов API.
Маршруты API предоставляют решение для создания публичного API с Next.js.
Любой файл внутри папки pages/api сопоставляется с /api/* и будет обрабатываться как конечная точка API вместо page. Они представляют собой только серверные пакеты и не увеличат размер вашего клиентского пакета.
Например, следующий маршрут API возвращает JSON-ответ со статусом 200:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ message: 'Hello from Next.js!' })
}Важно знать:
- Маршруты API не задают заголовки CORS, что означает, что они по умолчанию работают только с одним источником. Вы можете настроить это поведение, обернув обработчик запроса вспомогательными функциями для запросов CORS .
- Маршруты API не могут использоваться со статическими экспортами. Однако, Обработчики маршрутов в App Router могут.
- Маршруты API будут затронуты
pageExtensionsконфигурацией вnext.config.js.
- Маршруты API будут затронуты
Параметры
export default function handler(req: NextApiRequest, res: NextApiResponse) {
// ...
}
-
req: Экземпляр http.IncomingMessage -
res: Экземпляр http.ServerResponse
Методы HTTP
Для обработки различных методов HTTP в маршруте API вы можете использовать req.method в вашем обработчике запросов, как показано ниже:
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
// Process a POST request
} else {
// Handle any other HTTP method
}
}Вспомогательные функции запросов
Маршруты API предоставляют встроенные вспомогательные функции для запросов, которые анализируют входящий запрос (req):
-
req.cookies- Объект, содержащий куки, отправленные запросом. По умолчанию{} -
req.query- Объект, содержащий строку запроса. По умолчанию{} -
req.body- Объект, содержащий тело, проанализированноеcontent-type, илиnull, если тело не было отправлено
Настройка
Каждый маршрут API может экспортировать объект config для изменения стандартной конфигурации, которая выглядит следующим образом:
export const config = {
api: {
bodyParser: {
sizeLimit: '1mb',
},
},
// Specifies the maximum allowed duration for this function to execute (in seconds)
maxDuration: 5,
}
bodyParser автоматически включено. Если вы хотите обработать тело как Stream или с помощью raw-body, вы можете установить это значение в false.
Одно из применений отключения автоматического bodyParsing позволяет вам проверить исходное тело запроса веб-хука, например, от GitHub.
export const config = {
api: {
bodyParser: false,
},
}
bodyParser.sizeLimit — максимальный размер разрешенного анализируемого тела в любом формате, поддерживаемом bytes, например:
export const config = {
api: {
bodyParser: {
sizeLimit: '500kb',
},
},
}
externalResolver — явный флаг, указывающий серверу, что этот маршрут обрабатывается внешним решателем, таким как express или connect. Включение этого параметра отключает предупреждения о неразрешенных запросах.
export const config = {
api: {
externalResolver: true,
},
}
responseLimit автоматически включен, выдавая предупреждение, если тело ответа маршрута API превышает 4 МБ.
Если вы не используете Next.js в бессерверной среде и понимаете последствия для производительности отсутствия использования CDN или выделенного хоста для медиа, вы можете установить этот предел в false.
export const config = {
api: {
responseLimit: false,
},
}
responseLimit также может принимать количество байтов или любой строковый формат, поддерживаемый bytes, например, 1000, '500kb' или '3mb'. Это значение будет максимальным размером ответа перед отображением предупреждения. Значение по умолчанию — 4 МБ (см. выше).
export const config = {
api: {
responseLimit: '8mb',
},
}
Вспомогательные функции ответов
Объект ответа сервера Server Response object (часто сокращенно res) включает набор вспомогательных функций, похожих на Express.js, для улучшения опыта разработки и повышения скорости создания новых конечных точек API.
Включаемые вспомогательные функции:
-
res.status(code)- Функция для установки кода состояния.codeдолжен быть допустимым кодом состояния HTTP -
res.json(body)- Отправка JSON-ответа.bodyдолжен быть сериализуемым объектом -
res.send(body)- Отправка HTTP-ответа.bodyможет бытьstring,objectилиBuffer -
res.redirect([status,] path)- Перенаправление на указанный путь или URL.statusдолжен быть допустимым кодом состояния HTTP. Если не указано,statusпо умолчанию устанавливается в "307" ("Временное перенаправление"). -
res.revalidate(urlPath)- Перепроверка страницы по запросу с использованиемgetStaticProps.urlPathдолжен бытьstring.
Установка кода состояния ответа
При отправке ответа клиенту вы можете установить код состояния ответа.
В приведенном ниже примере код состояния ответа устанавливается в 200 (OK) и возвращается message со значением Hello from Next.js! в виде JSON-ответа:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ message: 'Hello from Next.js!' })
}Отправка JSON-ответа
При отправке ответа клиенту вы можете отправить JSON-ответ, который должен быть сериализуемым объектом. В реальном приложении вы можете уведомить клиента о состоянии запроса в зависимости от результата запрошенной конечной точки.
В следующем примере отправляется JSON-ответ со статусом 200 (OK) и результатом асинхронной операции. Он заключён в блок try-catch для обработки возможных ошибок, при этом соответствующий код состояния и сообщение об ошибке пойманы и отправлены клиенту:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
const result = await someAsyncOperation()
res.status(200).json({ result })
} catch (err) {
res.status(500).json({ error: 'failed to load data' })
}
}Отправка HTTP-ответа
Отправка HTTP-ответа выполняется так же, как и отправка JSON-ответа. Единственное различие заключается в том, что тело ответа может быть string, object или Buffer.
В следующем примере отправляется HTTP-ответ со статусом 200 (OK) и результатом асинхронной операции.
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
const result = await someAsyncOperation()
res.status(200).send({ result })
} catch (err) {
res.status(500).send({ error: 'failed to fetch data' })
}
}Перенаправление на указанный путь или URL
Рассмотрим пример формы, вы можете перенаправить клиента на указанный путь или URL после успешной отправки формы.
В следующем примере клиент перенаправляется на путь / после успешной отправки формы:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { name, message } = req.body
try {
await handleFormInputAsync({ name, message })
res.redirect(307, '/')
} catch (err) {
res.status(500).send({ error: 'Failed to fetch data' })
}
}Добавление типов TypeScript
Вы можете сделать свои маршруты API более безопасными с точки зрения типов, импортировав типы NextApiRequest и NextApiResponse из next, а также вы можете типизировать данные ответа:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
Важно знать: Тело
NextApiRequestявляетсяany, так как клиент может отправлять любые данные. Вы должны валидировать тип/структуру тела во время выполнения перед его использованием.
Динамические маршруты API
Маршруты API поддерживают динамические маршруты и следуют тем же правилам именования файлов, которые используются для pages/.
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const { pid } = req.query
res.end(`Post: ${pid}`)
}Теперь запрос к /api/post/abc вернёт текст: Post: abc.
Все маршруты API
Маршруты API могут быть расширены для обработки всех путей, добавив три точки (...) внутри скобок. Например:
-
pages/api/post/[...slug].jsсоответствует/api/post/a, но также/api/post/a/b,/api/post/a/b/cи так далее.
Важно знать: Вы можете использовать имена, отличные от
slug, например:[...param]
Сопоставленные параметры будут отправлены в качестве параметра запроса (slug в примере) на страницу, и он всегда будет массивом, поэтому путь /api/post/a будет иметь следующий query объект:
{ "slug": ["a"] }
И в случае /api/post/a/b, и любого другого соответствующего пути, новые параметры будут добавлены в массив, как показано ниже:
{ "slug": ["a", "b"] }
Например:
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const { slug } = req.query
res.end(`Post: ${slug.join(', ')}`)
}Теперь запрос к /api/post/a/b/c вернёт текст: Post: a, b, c.
Необязательные все маршруты API
Все маршруты могут быть сделаны необязательными, включив параметр в двойные скобки ([[...slug]]).
Например, pages/api/post/[[...slug]].js будет соответствовать /api/post, /api/post/a, /api/post/a/b, и так далее.
Главное отличие между универсальными и необязательными универсальными маршрутами заключается в том, что с необязательным маршрутом без параметра также будет сопоставляться (/api/post в примере выше).
query объекты выглядят следующим образом:
{ } // GET `/api/post` (empty object)
{ "slug": ["a"] } // `GET /api/post/a` (single-element array)
{ "slug": ["a", "b"] } // `GET /api/post/a/b` (multi-element array)
Ограничения
- Определённые маршруты API имеют приоритет над динамическими маршрутами API, а динамические маршруты API имеют приоритет над универсальными маршрутами API. Посмотрите на следующие примеры:
-
pages/api/post/create.js- Соответствует/api/post/create -
pages/api/post/[pid].js- Будет соответствовать/api/post/1,/api/post/abc, и т.д., но не/api/post/create -
pages/api/post/[...slug].js- Будет соответствовать/api/post/1/2,/api/post/a/b/c, и т.д., но не/api/post/create,/api/post/abc
-
Маршруты API кромки
Если вы хотите использовать маршруты API с Edge Runtime, мы рекомендуем поэтапно внедрять App Router и использовать обработчики маршрутов вместо этого.
Подпись функции обработчика маршрутов изоморфна, что означает, что вы можете использовать одну и ту же функцию как для Edge, так и для Node.js runtime.
© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/pages/building-your-application/routing/api-routes