web:api:prisma-fastify:p3

Ceci est une ancienne révision du document !


Objectif :

  • Valider proprement les entrées utilisateur
  • Éviter les “as any”
  • Centraliser les erreurs
  • Standardiser les réponses API

npm install zod


Nouvelle structure :

src/
 ├── errors/
 │     └── AppError.ts
 ├── schemas/
 │     ├── auth.schema.ts
 │     └── post.schema.ts
 ├── plugins/
 │     └── errorHandler.ts


`src/errors/AppError.ts`

export class AppError extends Error {
  statusCode: number

  constructor(message: string, statusCode = 400) {
    super(message)
    this.statusCode = statusCode
  }
}


`src/plugins/errorHandler.ts`

import { FastifyInstance } from "fastify"
import { ZodError } from "zod"
import { AppError } from "../errors/AppError"

export async function errorHandler(app: FastifyInstance) {
  app.setErrorHandler((error, request, reply) => {

    // Erreurs Zod
    if (error instanceof ZodError) {
      return reply.status(400).send({
        error: "Validation error",
        details: error.errors
      })
    }

    // Erreurs applicatives
    if (error instanceof AppError) {
      return reply.status(error.statusCode).send({
        error: error.message
      })
    }

    // Erreurs inattendues
    request.log.error(error)

    return reply.status(500).send({
      error: "Internal Server Error"
    })
  })
}


Dans `server.ts` :

import { errorHandler } from "./plugins/errorHandler"

app.register(errorHandler)

⚠️ À enregistrer après les autres plugins.


`src/schemas/auth.schema.ts`

import { z } from "zod"

export const registerSchema = z.object({
  name: z.string().min(2),
  email: z.string().email(),
  password: z.string().min(6)
})

export const loginSchema = z.object({
  email: z.string().email(),
  password: z.string().min(6)
})


Avant (dangereux) :

const { email, password } = request.body as any

Maintenant (safe) :

import { registerSchema } from "../schemas/auth.schema"

export async function register(request, reply) {

  const data = registerSchema.parse(request.body)

  const user = await authService.registerUser(data)

  return user
}

  • ✅ Si invalide → ZodError
  • ✅ Capturée automatiquement par le handler global

`auth.service.ts`

import { AppError } from "../errors/AppError"

async registerUser(data) {

  const existing = await prisma.user.findUnique({
    where: { email: data.email }
  })

  if (existing) {
    throw new AppError("Email already used", 409)
  }

  // logique création utilisateur
}


Erreurs validation :

{
  "error": "Validation error",
  "details": [...]
}

Erreurs métier :

{
  "error": "Email already used"
}

Erreur serveur :

{
  "error": "Internal Server Error"
}


  • web/api/prisma-fastify/p3.1772586467.txt.gz
  • Dernière modification : il y a 37 heures
  • de jcheron