Nuxt Nitro et Server Routes en 2026 : Full-Stack Vue et Points d'API

Guide complet sur Nuxt Nitro et les routes serveur en 2026. Apprenez à créer des API endpoints, gérer l'authentification et optimiser les performances pour des applications Vue full-stack.

Nuxt Nitro et Server Routes en 2026

Le développement full-stack avec Vue.js a considérablement évolué grâce à l'intégration de Nitro dans Nuxt. Ce moteur serveur universel permet aux développeurs de créer des applications complètes, du frontend au backend, dans un écosystème unifié. En 2026, les server routes de Nuxt représentent la méthode privilégiée pour construire des API robustes et performantes.

Nitro compile automatiquement les routes serveur pour différentes plateformes de déploiement, offrant une portabilité exceptionnelle entre Vercel, Cloudflare Workers, Netlify et les serveurs Node.js traditionnels.

Comprendre l'Architecture Nitro

Nitro constitue le cœur du système serveur de Nuxt 3 et versions ultérieures. Contrairement aux solutions traditionnelles, Nitro génère un code optimisé et minifié pour chaque environnement cible. Cette approche garantit des performances optimales indépendamment de la plateforme de déploiement.

L'architecture repose sur plusieurs composants fondamentaux :

  • H3 : Framework HTTP léger et performant
  • unjs : Collection d'utilitaires JavaScript universels
  • Rollup : Bundler pour la compilation du code serveur

Création des Premières Routes Serveur

Les routes serveur se définissent dans le répertoire server/ du projet Nuxt. Chaque fichier correspond automatiquement à un endpoint API basé sur sa structure de fichiers.

server/api/users.get.tstypescript
export default defineEventHandler(async (event) => {
  const users = await $fetch('/external-api/users')
  
  return {
    success: true,
    data: users,
    timestamp: Date.now()
  }
})

La convention de nommage détermine la méthode HTTP. Un fichier users.get.ts répond aux requêtes GET, tandis que users.post.ts gère les requêtes POST.

server/api/users.post.tstypescript
export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  
  // Validation des données
  if (!body.email || !body.name) {
    throw createError({
      statusCode: 400,
      statusMessage: 'Email and name are required'
    })
  }
  
  // Création de l'utilisateur
  const newUser = await createUser(body)
  
  return {
    success: true,
    data: newUser
  }
})

Gestion des Paramètres Dynamiques

Les routes dynamiques utilisent la syntaxe des crochets pour capturer les paramètres d'URL. Cette approche permet de créer des endpoints RESTful flexibles.

server/api/users/[id].get.tstypescript
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id')
  
  if (!id) {
    throw createError({
      statusCode: 400,
      statusMessage: 'User ID is required'
    })
  }
  
  const user = await fetchUserById(id)
  
  if (!user) {
    throw createError({
      statusCode: 404,
      statusMessage: 'User not found'
    })
  }
  
  return { data: user }
})

Pour les routes avec plusieurs segments dynamiques, la structure de répertoires reflète la hiérarchie de l'API.

server/api/organizations/[orgId]/members/[memberId].tstypescript
export default defineEventHandler(async (event) => {
  const orgId = getRouterParam(event, 'orgId')
  const memberId = getRouterParam(event, 'memberId')
  
  const member = await getOrganizationMember(orgId, memberId)
  
  return { data: member }
})

Middlewares et Intercepteurs

Les middlewares serveur permettent d'exécuter du code avant chaque requête. Cette fonctionnalité est essentielle pour l'authentification, la journalisation et la validation.

server/middleware/auth.tstypescript
export default defineEventHandler(async (event) => {
  const authHeader = getRequestHeader(event, 'authorization')
  
  if (event.path.startsWith('/api/protected')) {
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      throw createError({
        statusCode: 401,
        statusMessage: 'Authentication required'
      })
    }
    
    const token = authHeader.split(' ')[1]
    const user = await verifyToken(token)
    
    // Attacher l'utilisateur au contexte
    event.context.user = user
  }
})

Utilitaires Serveur et Helpers

Nuxt fournit de nombreux utilitaires pour simplifier le développement des routes serveur. Ces fonctions couvrent les cas d'utilisation courants.

server/api/upload.post.tstypescript
export default defineEventHandler(async (event) => {
  // Lecture du formulaire multipart
  const formData = await readMultipartFormData(event)
  
  if (!formData) {
    throw createError({
      statusCode: 400,
      statusMessage: 'No file uploaded'
    })
  }
  
  const file = formData.find(item => item.name === 'file')
  
  if (!file) {
    throw createError({
      statusCode: 400,
      statusMessage: 'File field is required'
    })
  }
  
  // Traitement du fichier
  const result = await processUpload(file)
  
  return {
    success: true,
    fileUrl: result.url
  }
})

Gestion des Cookies et Sessions

La manipulation des cookies est directe avec les utilitaires intégrés de Nitro.

server/api/auth/login.post.tstypescript
export default defineEventHandler(async (event) => {
  const { email, password } = await readBody(event)
  
  const user = await authenticateUser(email, password)
  
  if (!user) {
    throw createError({
      statusCode: 401,
      statusMessage: 'Invalid credentials'
    })
  }
  
  const sessionToken = generateSessionToken(user)
  
  // Définir le cookie de session
  setCookie(event, 'session', sessionToken, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
    maxAge: 60 * 60 * 24 * 7 // 7 jours
  })
  
  return {
    success: true,
    user: { id: user.id, email: user.email }
  }
})

Intégration avec les Bases de Données

Les routes serveur s'intègrent naturellement avec les ORM et les pilotes de base de données. L'exemple suivant utilise Drizzle ORM.

server/utils/db.tstypescript
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import * as schema from '~/server/database/schema'

const client = postgres(process.env.DATABASE_URL!)
export const db = drizzle(client, { schema })
server/api/posts/index.get.tstypescript
import { db } from '~/server/utils/db'
import { posts } from '~/server/database/schema'
import { desc } from 'drizzle-orm'

export default defineEventHandler(async (event) => {
  const query = getQuery(event)
  const page = Number(query.page) || 1
  const limit = Number(query.limit) || 10
  const offset = (page - 1) * limit
  
  const results = await db
    .select()
    .from(posts)
    .orderBy(desc(posts.createdAt))
    .limit(limit)
    .offset(offset)
  
  return {
    data: results,
    pagination: { page, limit }
  }
})

Mise en Cache et Performances

Nitro offre un système de cache intégré pour optimiser les performances des routes serveur.

server/api/stats.get.tstypescript
export default defineCachedEventHandler(async (event) => {
  // Cette réponse sera mise en cache pendant 60 secondes
  const stats = await computeExpensiveStats()
  
  return { data: stats }
}, {
  maxAge: 60,
  staleMaxAge: 120,
  swr: true
})

Pour un contrôle plus granulaire, le stockage du cache peut être configuré.

nuxt.config.tstypescript
export default defineNuxtConfig({
  nitro: {
    storage: {
      cache: {
        driver: 'redis',
        url: process.env.REDIS_URL
      }
    }
  }
})

Gestion des Erreurs Centralisée

Une gestion des erreurs cohérente améliore l'expérience développeur et la maintenabilité.

server/utils/errors.tstypescript
export class ApiError extends Error {
  statusCode: number
  
  constructor(message: string, statusCode: number = 500) {
    super(message)
    this.statusCode = statusCode
  }
}

export function handleApiError(error: unknown) {
  if (error instanceof ApiError) {
    throw createError({
      statusCode: error.statusCode,
      statusMessage: error.message
    })
  }
  
  console.error('Unexpected error:', error)
  
  throw createError({
    statusCode: 500,
    statusMessage: 'Internal server error'
  })
}
server/api/orders/[id].get.tstypescript
import { handleApiError, ApiError } from '~/server/utils/errors'

export default defineEventHandler(async (event) => {
  try {
    const id = getRouterParam(event, 'id')
    const order = await getOrder(id)
    
    if (!order) {
      throw new ApiError('Order not found', 404)
    }
    
    return { data: order }
  } catch (error) {
    handleApiError(error)
  }
})

WebSockets et Temps Réel

Nitro supporte les WebSockets pour les fonctionnalités temps réel.

server/api/ws.tstypescript
export default defineWebSocketHandler({
  open(peer) {
    console.log('Client connected:', peer.id)
    peer.send(JSON.stringify({ type: 'connected', id: peer.id }))
  },
  
  message(peer, message) {
    const data = JSON.parse(message.text())
    
    // Broadcast à tous les pairs connectés
    peer.publish('chat', JSON.stringify({
      from: peer.id,
      ...data
    }))
  },
  
  close(peer) {
    console.log('Client disconnected:', peer.id)
  }
})

Prêt à réussir tes entretiens Vue.js / Nuxt.js ?

Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.

Déploiement Multi-Plateforme

L'un des avantages majeurs de Nitro réside dans sa capacité à cibler différentes plateformes de déploiement sans modification du code.

nuxt.config.tstypescript
export default defineNuxtConfig({
  nitro: {
    // Pour Cloudflare Workers
    preset: 'cloudflare-pages',
    
    // Ou pour Node.js standalone
    // preset: 'node-server',
    
    // Ou pour Vercel
    // preset: 'vercel-edge'
  }
})

La portabilité du code serveur entre les environnements edge et les serveurs traditionnels représente un avantage considérable pour les équipes souhaitant optimiser les coûts et les performances selon les besoins.

Conclusion

Les routes serveur Nuxt propulsées par Nitro transforment le développement full-stack Vue.js. La simplicité de création des API, combinée à la puissance du système de cache et la portabilité multi-plateforme, en fait une solution de choix pour les projets modernes. La maîtrise de ces concepts permet de construire des applications performantes et maintenables, tout en conservant la flexibilité nécessaire pour évoluer avec les besoins du projet.

Tags

#nuxt
#nitro
#vue
#server-routes
#api
#full-stack

Partager

Articles similaires