Spec-Zone.ru › Next.js

Маршруты API

Примеры
  • Базовые маршруты API
  • Вспомогательные функции для запросов маршрутов API
  • Маршруты API с GraphQL
  • Маршруты API с REST
  • Маршруты API с CORS

Важно знать: Если вы используете 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.

Параметры

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API