Routes API
Exemples
Bon à savoir : Si vous utilisez le routeur App, vous pouvez utiliser les Composants Serveur ou les Gestionnaires de Route à la place des Routes API.
Les routes API offrent une solution pour construire une API publique avec Next.js.
Tout fichier dans le dossier pages/api
est mappé vers /api/*
et sera traité comme un point de terminaison API plutôt qu'une page
. Ce sont des bundles exclusivement côté serveur qui n'augmenteront pas la taille de votre bundle côté client.
Par exemple, la route API suivante renvoie une réponse JSON avec un code de statut 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!' })
}
export default function handler(req, res) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
Bon à savoir :
- Les Routes API ne spécifient pas d'en-têtes CORS, ce qui signifie qu'elles sont uniquement de même origine par défaut. Vous pouvez personnaliser ce comportement en enveloppant le gestionnaire de requête avec les helpers de requête CORS.
- Les Routes API ne peuvent pas être utilisées avec les exports statiques. Cependant, les Gestionnaires de Route dans le routeur App le peuvent.
- Les Routes API seront affectées par la configuration
pageExtensions
dansnext.config.js
.
Paramètres
export default function handler(req: NextApiRequest, res: NextApiResponse) {
// ...
}
req
: Une instance de http.IncomingMessageres
: Une instance de http.ServerResponse
Méthodes HTTP
Pour gérer différentes méthodes HTTP dans une route API, vous pouvez utiliser req.method
dans votre gestionnaire de requête, comme ceci :
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
// Traiter une requête POST
} else {
// Gérer toute autre méthode HTTP
}
}
export default function handler(req, res) {
if (req.method === 'POST') {
// Traiter une requête POST
} else {
// Gérer toute autre méthode HTTP
}
}
Helpers de Requête
Les Routes API fournissent des helpers de requête intégrés qui analysent la requête entrante (req
) :
req.cookies
- Un objet contenant les cookies envoyés par la requête. Par défaut{}
req.query
- Un objet contenant la chaîne de requête. Par défaut{}
req.body
- Un objet contenant le corps analysé parcontent-type
, ounull
si aucun corps n'a été envoyé
Configuration personnalisée
Chaque Route API peut exporter un objet config
pour modifier la configuration par défaut, qui est la suivante :
export const config = {
api: {
bodyParser: {
sizeLimit: '1mb',
},
},
// Spécifie la durée maximale autorisée pour l'exécution de cette fonction (en secondes)
maxDuration: 5,
}
bodyParser
est activé automatiquement. Si vous souhaitez consommer le corps comme un Stream
ou avec raw-body
, vous pouvez le désactiver en le définissant sur false
.
Un cas d'utilisation pour désactiver l'bodyParser
automatique est de vous permettre de vérifier le corps brut d'une requête webhook, par exemple depuis GitHub.
export const config = {
api: {
bodyParser: false,
},
}
bodyParser.sizeLimit
est la taille maximale autorisée pour le corps analysé, dans tout format pris en charge par bytes, comme ceci :
export const config = {
api: {
bodyParser: {
sizeLimit: '500kb',
},
},
}
externalResolver
est un indicateur explicite qui indique au serveur que cette route est gérée par un résolveur externe comme express ou connect. Activer cette option désactive les avertissements pour les requêtes non résolues.
export const config = {
api: {
externalResolver: true,
},
}
responseLimit
est activé automatiquement, avertissant lorsque le corps de la réponse d'une Route API dépasse 4Mo.
Si vous n'utilisez pas Next.js dans un environnement serverless, et que vous comprenez les implications en termes de performance de ne pas utiliser un CDN ou un hébergement média dédié, vous pouvez désactiver cette limite en la définissant sur false
.
export const config = {
api: {
responseLimit: false,
},
}
responseLimit
peut également prendre un nombre d'octets ou toute chaîne de format prise en charge par bytes
, par exemple 1000
, '500kb'
ou '3mb'
.
Cette valeur sera la taille maximale de la réponse avant qu'un avertissement ne soit affiché. Par défaut 4Mo (voir ci-dessus).
export const config = {
api: {
responseLimit: '8mb',
},
}
Helpers de Réponse
L'objet Réponse du Serveur (souvent abrégé en res
) inclut un ensemble de méthodes helpers similaires à Express.js pour améliorer l'expérience développeur et accélérer la création de nouveaux points de terminaison API.
Les helpers inclus sont :
res.status(code)
- Une fonction pour définir le code de statut.code
doit être un code de statut HTTP valideres.json(body)
- Envoie une réponse JSON.body
doit être un objet sérialisableres.send(body)
- Envoie la réponse HTTP.body
peut être unestring
, unobject
ou unBuffer
res.redirect([status,] path)
- Redirige vers un chemin ou une URL spécifiée.status
doit être un code de statut HTTP valide. Si non spécifié,status
est par défaut "307" "Redirection temporaire".res.revalidate(urlPath)
- Révalider une page à la demande en utilisantgetStaticProps
.urlPath
doit être unestring
.
Définir le code de statut d'une réponse
Lors de l'envoi d'une réponse au client, vous pouvez définir le code de statut de la réponse.
L'exemple suivant définit le code de statut de la réponse à 200
(OK
) et renvoie une propriété message
avec la valeur Hello from Next.js!
comme réponse 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!' })
}
export default function handler(req, res) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
Envoyer une réponse JSON
Lors de l'envoi d'une réponse au client, vous pouvez envoyer une réponse JSON, qui doit être un objet sérialisable. Dans une application réelle, vous pourriez vouloir informer le client du statut de la requête en fonction du résultat du point de terminaison demandé.
L'exemple suivant envoie une réponse JSON avec le code de statut 200
(OK
) et le résultat de l'opération asynchrone. Il est contenu dans un bloc try catch pour gérer les erreurs éventuelles, avec le code de statut et le message d'erreur appropriés capturés et renvoyés au client :
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: 'Échec du chargement des données' })
}
}
export default async function handler(req, res) {
try {
const result = await someAsyncOperation()
res.status(200).json({ result })
} catch (err) {
res.status(500).json({ error: 'Échec du chargement des données' })
}
}
Envoyer une réponse HTTP
L'envoi d'une réponse HTTP fonctionne de la même manière que l'envoi d'une réponse JSON. La seule différence est que le corps de la réponse peut être une string
, un object
ou un Buffer
.
L'exemple suivant envoie une réponse HTTP avec le code de statut 200
(OK
) et le résultat de l'opération asynchrone.
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: 'Échec de la récupération des données' })
}
}
export default async function handler(req, res) {
try {
const result = await someAsyncOperation()
res.status(200).send({ result })
} catch (err) {
res.status(500).send({ error: 'Échec de la récupération des données' })
}
}
Rediriger vers un chemin ou une URL spécifié
Prenons un formulaire comme exemple, vous pourriez vouloir rediriger votre client vers un chemin ou une URL spécifié une fois qu'il a soumis le formulaire.
L'exemple suivant redirige le client vers le chemin /
si le formulaire est soumis avec succès :
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: 'Échec de la récupération des données' })
}
}
export default async function handler(req, res) {
const { name, message } = req.body
try {
await handleFormInputAsync({ name, message })
res.redirect(307, '/')
} catch (err) {
res.status(500).send({ error: 'Échec de la récupération des données' })
}
}
Ajouter des types TypeScript
Vous pouvez rendre vos Routes API plus typées en important les types NextApiRequest
et NextApiResponse
depuis next
, en plus de ceux-ci, vous pouvez également typer vos données de réponse :
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!' })
}
Bon à savoir : Le corps de
NextApiRequest
estany
car le client peut inclure n'importe quelle charge utile. Vous devriez valider le type/la forme du corps à l'exécution avant de l'utiliser.
Routes API Dynamiques
Les Routes API prennent en charge les routes dynamiques, et suivent les mêmes règles de nommage de fichiers que celles utilisées pour pages/
.
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const { pid } = req.query
res.end(`Post: ${pid}`)
}
export default function handler(req, res) {
const { pid } = req.query
res.end(`Post: ${pid}`)
}
Maintenant, une requête vers /api/post/abc
répondra avec le texte : Post: abc
.
Routes API attrape-tout
Les Routes API peuvent être étendues pour attraper tous les chemins en ajoutant trois points (...
) à l'intérieur des crochets. Par exemple :
pages/api/post/[...slug].js
correspondra à/api/post/a
, mais aussi à/api/post/a/b
,/api/post/a/b/c
, etc.
Bon à savoir : Vous pouvez utiliser d'autres noms que
slug
, comme :[...param]
Les paramètres correspondants seront envoyés comme paramètre de requête (slug
dans l'exemple) à la page, et ce sera toujours un tableau, donc, le chemin /api/post/a
aura l'objet query
suivant :
{ "slug": ["a"] }
Et dans le cas de /api/post/a/b
, et tout autre chemin correspondant, de nouveaux paramètres seront ajoutés au tableau, comme ceci :
{ "slug": ["a", "b"] }
Par exemple :
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const { slug } = req.query
res.end(`Post: ${slug.join(', ')}`)
}
export default function handler(req, res) {
const { slug } = req.query
res.end(`Post: ${slug.join(', ')}`)
}
Maintenant, une requête vers /api/post/a/b/c
répondra avec le texte : Post: a, b, c
.
Routes API attrape-tout optionnelles
Les routes attrape-tout peuvent être rendues optionnelles en incluant le paramètre dans des doubles crochets ([[...slug]]
).
Par exemple, pages/api/post/[[...slug]].js
correspondra à /api/post
, /api/post/a
, /api/post/a/b
, etc.
La principale différence entre les routes attrape-tout et attrape-tout optionnelles est qu'avec les optionnelles, la route sans le paramètre est également correspondante (/api/post
dans l'exemple ci-dessus).
Les objets query
sont les suivants :
{ } // GET `/api/post` (objet vide)
{ "slug": ["a"] } // `GET /api/post/a` (tableau à un élément)
{ "slug": ["a", "b"] } // `GET /api/post/a/b` (tableau à plusieurs éléments)
Mises en garde
- Les Routes API prédéfinies prennent le pas sur les Routes API dynamiques, et les Routes API dynamiques prennent le pas sur les Routes API attrape-tout. Regardez les exemples suivants :
pages/api/post/create.js
- Correspondra à/api/post/create
pages/api/post/[pid].js
- Correspondra à/api/post/1
,/api/post/abc
, etc. Mais pas à/api/post/create
pages/api/post/[...slug].js
- Correspondra à/api/post/1/2
,/api/post/a/b/c
, etc. Mais pas à/api/post/create
,/api/post/abc
Routes API Edge
Si vous souhaitez utiliser les Routes API avec le Runtime Edge, nous recommandons d'adopter progressivement le routeur App et d'utiliser les Gestionnaires de Route à la place.
La signature des Gestionnaires de Route est isomorphe, ce qui signifie que vous pouvez utiliser la même fonction pour les runtimes Edge et Node.js.