Maison >interface Web >js tutoriel >Gestion personnalisée des erreurs dans une API REST à l'aide de TypeScript, Express.js, validation Joi et programmation orientée objet

Gestion personnalisée des erreurs dans une API REST à l'aide de TypeScript, Express.js, validation Joi et programmation orientée objet

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBoriginal
2024-07-27 20:41:121170parcourir

Custom error handling in a REST API using TypeScript, Express.js, Joi validation, and object-oriented programming

Salut les développeurs !

La création d'une API REST robuste et maintenable nécessite un examen attentif de la gestion des erreurs, de la validation et de la structure. Dans cet article, nous explorerons comment configurer un mécanisme personnalisé de gestion des erreurs dans une API REST à l'aide de TypeScript, Express.js, Joi pour la validation et les principes de programmation orientée objet (POO). Nous structurerons notre projet comme suit :

Structure :

---src
-----middlewares
--------ErrorHanlder.ts
-----modèles
--------Utilisateur.ts
-----référentiel
--------UserRepository.ts
-----itinéraires
--------UserRouter.ts
-----contrôleurs
--------UserController.ts
-----services
---------UserService.ts
-----validations
--------UserValidation.ts
---app.ts
---server.ts

Mise en place du projet

mkdir rest-api
cd rest-api
npm init -y
npm install express typescript @types/node @types/express ts-node-dev
npx tsc --init

Middleware pour la gestion des erreurs

// src/middlewares/ErrorHandler.ts
import { Request, Response, NextFunction } from 'express';

class ErrorHandler extends Error {
  statusCode: number;
  message: string;

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

const handleError = (err: ErrorHandler, req: Request, res: Response, next: NextFunction) => {
  const { statusCode, message } = err;
  res.status(statusCode).json({
    status: 'error',
    statusCode,
    message,
  });
};

export { ErrorHandler, handleError };

Modèle utilisateur

// src/models/User.ts
export interface User {
  id: number;
  name: string;
  email: string;
}

Référentiel d'utilisateurs

// src/repository/UserRepository.ts
import { User } from '../models/User';

class UserRepository {
  private users: User[] = [];

  findAll(): User[] {
    return this.users;
  }

  findById(id: number): User | undefined {
    return this.users.find(user => user.id === id);
  }

  create(user: User): User {
    this.users.push(user);
    return user;
  }
}

export default new UserRepository();

Service utilisateur

// src/services/UserService.ts
import UserRepository from '../repository/UserRepository';
import { User } from '../models/User';
import { ErrorHandler } from '../middlewares/ErrorHandler';

class UserService {
  getAllUsers(): User[] {
    return UserRepository.findAll();
  }

  getUserById(id: number): User | undefined {
    const user = UserRepository.findById(id);
    if (!user) {
      throw new ErrorHandler(404, 'User not found');
    }
    return user;
  }

  createUser(user: User): User {
    const { error } = userSchema.validate(user);
    if (error) {
      throw new ErrorHandler(400, error.details[0].message);
    }
    return UserRepository.create(user);
  }
}

export default new UserService();


Validation utilisateur

// src/validations/UserValidation.ts
import Joi from 'joi';

const userSchema = Joi.object({
  id: Joi.number().required(),
  name: Joi.string().required(),
  email: Joi.string().email().required(),
});

export { userSchema };

Contrôleur utilisateur

// src/controllers/UserController.ts
import { Request, Response, NextFunction } from 'express';
import UserService from '../services/UserService';
import { ErrorHandler } from '../middlewares/ErrorHandler';

class UserController {
  getAllUsers(req: Request, res: Response, next: NextFunction) {
    try {
      const users = UserService.getAllUsers();
      res.json(users);
    } catch (error) {
      next(error);
    }
  }

  getUserById(req: Request, res: Response, next: NextFunction) {
    try {
      const user = UserService.getUserById(parseInt(req.params.id));
      res.json(user);
    } catch (error) {
      next(error);
    }
  }

  createUser(req: Request, res: Response, next: NextFunction) {
    try {
      const user = UserService.createUser(req.body);
      res.status(201).json(user);
    } catch (error) {
      next(error);
    }
  }
}

export default new UserController();


Itinéraires utilisateur

// src/routes/UserRouter.ts
import { Router } from 'express';
import UserController from '../controllers/UserController';

const router = Router();

router.get('/users', UserController.getAllUsers);
router.get('/users/:id', UserController.getUserById);
router.post('/users', UserController.createUser);

export default router;

Point d'entrée de l'application

// src/app.ts
import express from 'express';
import UserRouter from './routes/UserRouter';
import { handleError } from './middlewares/ErrorHandler';

const app = express();

app.use(express.json());
app.use('/api', UserRouter);
app.use(handleError);

export default app;

Configuration du serveur

// src/server.ts
import app from './app';

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

En structurant notre projet à l'aide des principes TypeScript, Express.js, Joi et POO, nous obtenons une base de code propre et maintenable. Le middleware personnalisé de gestion des erreurs fournit un moyen cohérent de gérer les erreurs dans l'ensemble de l'application, tandis que la logique de validation garantit l'intégrité des données. Cette configuration peut servir de base solide pour des applications plus complexes.

Contacts
E-mail : luizcalaca@gmail.com
Instagram : https://www.instagram.com/luizcalaca
Linkedin : https://www.linkedin.com/in/luizcalaca/
Twitter : https://twitter.com/luizcalaca

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn