Apprenez à exploiter les Routes d'API Next.js pour créer des backends serverless directement dans votre application Next.js. Ce guide couvre tout, de la configuration de base aux techniques avancées pour gérer l'authentification, la persistance des données, et plus encore.
Routes d'API Next.js : Créez Votre Backend en Toute Simplicité
Next.js a révolutionné le développement front-end avec ses fonctionnalités puissantes et sa structure intuitive. Mais saviez-vous qu'il peut aussi simplifier considérablement le développement backend ? Les Routes d'API Next.js vous permettent de créer des points de terminaison d'API serverless (sans serveur) directement au sein de votre application Next.js, éliminant dans de nombreux cas le besoin d'un serveur backend distinct. Ce guide complet vous guidera à travers le processus de création d'un backend robuste et évolutif à l'aide des Routes d'API Next.js.
Que sont les Routes d'API Next.js ?
Les Routes d'API sont des fonctions serverless que vous créez dans le répertoire /pages/api
de votre projet Next.js. Ces fonctions gèrent les requêtes HTTP entrantes et retournent des réponses, tout comme une API backend traditionnelle. La différence principale est qu'elles sont déployées en tant que fonctions serverless, ce qui signifie que vous n'avez pas à gérer de serveurs ou d'infrastructure.
Considérez-les comme des fonctions backend légères et à la demande, parfaitement intégrées à votre front-end Next.js.
Avantages de l'Utilisation des Routes d'API Next.js
- Développement Simplifié : Écrivez votre code front-end et backend dans le même projet, en utilisant JavaScript ou TypeScript. Fini le changement de contexte entre différents projets et technologies.
- Architecture Serverless : Profitez de l'évolutivité, de la fiabilité et de la rentabilité du "serverless computing". Ne payez que pour les ressources que vous consommez.
- Déploiement Facile : Déployez l'ensemble de votre application (front-end et backend) avec une seule commande en utilisant des plateformes comme Vercel ou Netlify.
- Sécurité Intégrée : Next.js et les plateformes serverless fournissent des fonctionnalités de sécurité intégrées pour protéger vos points de terminaison d'API.
- Performances Améliorées : Les Routes d'API peuvent être déployées plus près de vos utilisateurs, réduisant la latence et améliorant les performances, ce qui est particulièrement avantageux pour les utilisateurs du monde entier.
- Réutilisabilité du Code : Partagez du code entre votre front-end et votre backend, réduisant la duplication de code et améliorant la maintenabilité.
Démarrer avec les Routes d'API Next.js
Créons une route d'API simple qui retourne une réponse JSON. Assurez-vous d'abord d'avoir un projet Next.js configuré. Sinon, créez-en un avec :
npx create-next-app my-app
cd my-app
Maintenant, créez un fichier nommé hello.js
dans le répertoire /pages/api
:
// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
Ce code définit une route d'API simple qui répond avec un objet JSON contenant le nom "John Doe". Pour accéder à cette route d'API, démarrez votre serveur de développement Next.js :
npm run dev
Ensuite, ouvrez votre navigateur et accédez à http://localhost:3000/api/hello
. Vous devriez voir la réponse JSON suivante :
{"name": "John Doe"}
Comprendre le Gestionnaire de Route d'API
La fonction handler
dans votre route d'API reçoit deux arguments :
req
: Une instance dehttp.IncomingMessage
, qui contient des informations sur la requête entrante, telles que la méthode de la requête, les en-têtes et le corps.res
: Une instance dehttp.ServerResponse
, qui vous permet de renvoyer une réponse au client.
Vous pouvez utiliser ces objets pour gérer différents types de requêtes, lire les données du corps de la requête, définir les en-têtes de réponse et envoyer différents types de réponses.
Gérer les Différentes Méthodes HTTP
Vous pouvez utiliser la propriété req.method
pour déterminer la méthode HTTP de la requête entrante et gérer différentes méthodes en conséquence. Par exemple :
// pages/api/method.js
export default function handler(req, res) {
if (req.method === 'GET') {
// Gérer la requête GET
res.status(200).json({ message: 'Ceci est une requête GET' })
} else if (req.method === 'POST') {
// Gérer la requête POST
res.status(200).json({ message: 'Ceci est une requête POST' })
} else {
// Gérer les autres méthodes
res.status(405).json({ message: 'Méthode non autorisée' })
}
}
Dans cet exemple, la route d'API gère à la fois les requêtes GET et POST. Si la méthode de la requête est GET, elle répond avec un objet JSON contenant le message "Ceci est une requête GET". Si la méthode de la requête est POST, elle répond avec un objet JSON contenant le message "Ceci est une requête POST". Si la méthode de la requête est autre, elle répond avec une erreur 405 Method Not Allowed.
Lire les Données du Corps de la Requête
Pour les requêtes POST, PUT et PATCH, vous devez souvent lire les données du corps de la requête. Next.js fournit un support intégré pour l'analyse des corps de requête JSON et URL-encodés. Pour analyser un corps de requête JSON, vous pouvez utiliser la propriété req.body
. Par exemple :
// pages/api/post.js
export default async function handler(req, res) {
if (req.method === 'POST') {
const { name, email } = req.body
// Traiter les données
console.log('Nom :', name)
console.log('Email :', email)
res.status(200).json({ message: 'Données reçues avec succès' })
} else {
res.status(405).json({ message: 'Méthode non autorisée' })
}
}
Pour tester cette route d'API, vous pouvez utiliser un outil comme Postman ou curl pour envoyer une requête POST avec un corps JSON :
curl -X POST -H "Content-Type: application/json" -d '{"name": "Jane Doe", "email": "jane.doe@example.com"}' http://localhost:3000/api/post
Définir les En-têtes de Réponse
Vous pouvez utiliser la méthode res.setHeader()
pour définir les en-têtes de réponse. C'est utile pour définir le type de contenu, le contrôle du cache et d'autres informations importantes. Par exemple :
// pages/api/headers.js
export default function handler(req, res) {
res.setHeader('Content-Type', 'application/json')
res.setHeader('Cache-Control', 's-maxage=3600')
res.status(200).json({ message: 'Bonjour, le monde !' })
}
Dans cet exemple, la route d'API définit l'en-tête Content-Type
à application/json
, indiquant que la réponse est un objet JSON. Elle définit également l'en-tête Cache-Control
à s-maxage=3600
, ce qui indique au navigateur et au CDN de mettre en cache la réponse jusqu'à 1 heure.
Gestion des Erreurs
Il est important de gérer les erreurs avec élégance dans vos routes d'API. Vous pouvez utiliser des blocs try-catch pour attraper les exceptions et envoyer des réponses d'erreur appropriées au client. Par exemple :
// pages/api/error.js
export default async function handler(req, res) {
try {
// Simuler une erreur
throw new Error('Quelque chose s\'est mal passé')
} catch (error) {
console.error(error)
res.status(500).json({ message: 'Erreur interne du serveur' })
}
}
Dans cet exemple, la route d'API simule une erreur en lançant un nouvel objet Error
. Le bloc catch attrape l'erreur, la consigne dans la console et envoie une réponse 500 Erreur Interne du Serveur au client. Envisagez d'utiliser un système de journalisation robuste comme Sentry ou Datadog pour les environnements de production.
Se Connecter à une Base de Données
L'un des cas d'utilisation les plus courants pour les routes d'API est la connexion à une base de données. Les Routes d'API Next.js s'intègrent de manière transparente avec diverses bases de données, notamment :
- MongoDB : Une base de données NoSQL populaire, bien adaptée aux données flexibles et non structurées.
- PostgreSQL : Une base de données relationnelle open-source puissante, reconnue pour sa fiabilité et l'intégrité de ses données.
- MySQL : Une autre base de données relationnelle open-source populaire, largement utilisée pour les applications web.
- Firebase : Une plateforme basée sur le cloud qui fournit une base de données en temps réel et d'autres services.
- FaunaDB : Une base de données serverless conçue pour les applications mondiales.
Voici un exemple de connexion à une base de données MongoDB dans une route d'API Next.js :
// pages/api/mongodb.js
import { MongoClient } from 'mongodb'
const uri = process.env.MONGODB_URI
const options = {}
let client
let clientPromise
if (!process.env.MONGODB_URI) {
throw new Error('Veuillez ajouter votre URI Mongo à .env.local')
}
if (process.env.NODE_ENV === 'development') {
// En mode développement, utilisez une variable globale afin que la valeur
// est préservée lors des rechargements de modules causés par HMR (Hot Module Replacement).
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options)
global._mongoClientPromise = client.connect()
}
clientPromise = global._mongoClientPromise
} else {
// En mode production, il est préférable de ne pas utiliser de variable globale.
client = new MongoClient(uri, options)
clientPromise = client.connect()
}
// Exporter une promesse MongoClient à portée de module. En faisant cela dans un
// module séparé, le client peut être réutilisé en toute sécurité à travers plusieurs
// fonctions. Voir : https://github.com/vercel/next.js/blob/canary/examples/with-mongodb/lib/mongodb.js
export default async function handler(req, res) {
try {
const client = await clientPromise
const db = client.db(process.env.MONGODB_DB)
const collection = db.collection('users')
const users = await collection.find({}).toArray()
res.status(200).json({ users })
} catch (e) {
console.error(e)
res.status(500).json({ message: 'Échec de la récupération des utilisateurs' })
}
}
Avant d'exécuter ce code, assurez-vous que le paquet mongodb
est installé :
npm install mongodb
Vous devez également définir les variables d'environnement MONGODB_URI
et MONGODB_DB
. Ces variables doivent être définies dans votre fichier .env.local
(ou dans les paramètres des variables d'environnement de votre hébergeur pour la production). Le MONGODB_URI
contient la chaîne de connexion à votre base de données MongoDB, et MONGODB_DB
spécifie le nom de la base de données.
Authentification et Autorisation
Protéger vos routes d'API est crucial pour la sécurité. Les Routes d'API Next.js peuvent être sécurisées en utilisant diverses techniques d'authentification et d'autorisation, notamment :
- Jetons Web JSON (JWT) : Une norme pour transmettre en toute sécurité des informations entre les parties sous forme d'objet JSON.
- Clés d'API : Un moyen simple de restreindre l'accès à vos points de terminaison d'API.
- OAuth : Un protocole de délégation qui permet aux utilisateurs d'accorder aux applications tierces l'accès à leurs ressources sans partager leurs identifiants.
- NextAuth.js : Une solution d'authentification open-source complète pour les applications Next.js.
Voici un exemple de protection d'une route d'API utilisant l'authentification JWT :
// pages/api/protected.js
import jwt from 'jsonwebtoken'
const secret = process.env.JWT_SECRET
export default function handler(req, res) {
const token = req.headers.authorization?.split(' ')[1]
if (!token) {
return res.status(401).json({ message: 'Non autorisé' })
}
try {
const decoded = jwt.verify(token, secret)
// L'objet \"decoded\" contient les informations utilisateur intégrées dans le jeton
// Par exemple : const userId = decoded.userId;
// Continuer le traitement de la requête
res.status(200).json({ message: 'Accès à la ressource protégée réussi' })
} catch (error) {
return res.status(401).json({ message: 'Jeton invalide' })
}
}
Avant d'exécuter ce code, assurez-vous que le paquet jsonwebtoken
est installé :
npm install jsonwebtoken
Vous devez également définir la variable d'environnement JWT_SECRET
. Il doit s'agir d'une clé secrète forte, générée de manière aléatoire, utilisée pour signer et vérifier les JWT. Stockez-la en toute sécurité et ne l'exposez jamais dans votre code côté client.
Middleware
Bien que Next.js n'offre pas de middleware traditionnel pour les routes d'API de la même manière qu'Express.js, vous pouvez obtenir une fonctionnalité similaire en enveloppant vos gestionnaires de routes d'API avec des fonctions réutilisables. Cela vous permet d'effectuer des tâches telles que :
- Authentification : Vérifier les identifiants de l'utilisateur avant d'autoriser l'accès aux points de terminaison de l'API.
- Autorisation : Vérifier si un utilisateur dispose des autorisations nécessaires pour effectuer une action spécifique.
- Journalisation : Enregistrer les requêtes entrantes et les réponses sortantes à des fins d'audit et de débogage.
- Validation : Valider les données de la requête pour s'assurer qu'elles répondent à des critères spécifiques.
- Limitation de Débit (Rate Limiting) : Protéger votre API contre les abus en limitant le nombre de requêtes qu'un utilisateur peut effectuer dans un laps de temps donné.
Voici un exemple de création d'un middleware de journalisation simple :
// utils/middleware.js
export function withLogging(handler) {
return async function(req, res) {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`)
return handler(req, res)
}
}
Pour utiliser ce middleware, enveloppez simplement votre gestionnaire de route d'API avec la fonction withLogging
:
// pages/api/logged.js
import { withLogging } from '../../utils/middleware'
async function handler(req, res) {
res.status(200).json({ message: 'Cette requête a été journalisée' })
}
export default withLogging(handler)
Meilleures Pratiques pour Créer des Routes d'API Next.js
- Gardez vos routes d'API petites et ciblées. Chaque route d'API doit gérer une tâche ou une ressource spécifique.
- Utilisez des variables d'environnement pour les données sensibles. Ne codez jamais en dur des secrets ou des clés d'API dans votre code.
- Validez les données de la requête pour prévenir les vulnérabilités de sécurité. Utilisez une bibliothèque comme Joi ou Yup pour valider les corps de requête.
- Gérez les erreurs avec élégance et fournissez des messages d'erreur informatifs. Utilisez des blocs try-catch et consignez les erreurs dans un emplacement centralisé.
- Utilisez la mise en cache pour améliorer les performances. Mettez en cache les données fréquemment consultées pour réduire la charge de la base de données.
- Surveillez vos routes d'API pour les performances et les erreurs. Utilisez un outil de surveillance comme Sentry ou Datadog pour suivre la santé de votre API.
- Documentez vos routes d'API à l'aide d'un outil comme Swagger ou OpenAPI. Cela facilite l'utilisation de votre API par d'autres développeurs.
- Envisagez d'utiliser TypeScript pour la sécurité des types. TypeScript peut vous aider à détecter les erreurs plus tôt et à améliorer la maintenabilité de votre code.
- Pensez à l'internationalisation (i18n) dès le départ. Si votre application sera utilisée par des utilisateurs de différents pays, concevez vos routes d'API pour prendre en charge plusieurs langues et devises. Par exemple, les points de terminaison d'API pour le commerce électronique pourraient devoir gérer différents taux de taxe et frais d'expédition en fonction de l'emplacement de l'utilisateur.
- Implémentez une configuration CORS (Cross-Origin Resource Sharing) appropriée. C'est crucial lorsque votre API est accessible depuis un domaine différent de celui de votre application Next.js. Configurez soigneusement CORS pour autoriser uniquement les origines autorisées à accéder aux ressources de votre API.
Techniques Avancées
Tâches en Arrière-plan (Background Jobs)
Pour les tâches de longue durée qui ne devraient pas bloquer la réponse de l'API, envisagez d'utiliser des tâches en arrière-plan. Vous pouvez utiliser des bibliothèques comme BullMQ ou Bree pour gérer vos tâches en arrière-plan et les traiter de manière asynchrone.
WebSockets
Pour les applications en temps réel, vous pouvez utiliser les WebSockets dans vos routes d'API Next.js. Des bibliothèques comme Socket.IO et ws facilitent l'établissement de connexions persistantes entre le client et le serveur.
GraphQL
Si vous avez besoin d'un moyen plus flexible et efficace pour récupérer des données, envisagez d'utiliser GraphQL. Vous pouvez utiliser des bibliothèques comme Apollo Server ou Yoga pour créer un point de terminaison d'API GraphQL dans votre application Next.js.
Conclusion
Les Routes d'API Next.js offrent un moyen puissant et pratique de créer des backends serverless directement au sein de votre application Next.js. En tirant parti des avantages de l'architecture serverless, vous pouvez simplifier le développement, améliorer les performances et réduire les coûts. Que vous construisiez un simple formulaire de contact ou une plateforme de commerce électronique complexe, les Routes d'API Next.js peuvent vous aider à créer un backend robuste et évolutif en toute simplicité. Avec une solide compréhension des fondamentaux et l'application des meilleures pratiques, vous pouvez exploiter cet outil puissant pour créer des applications efficaces, sécurisées et accessibles à l'échelle mondiale.