Crafting a Robust Express + TypeScript Backend pour le suivi des finances personnelles

Lorsqu'il s'agit de créer un système de suivi des finances personnelles, il est essentiel d'assurer l'intégrité des données et la fiabilité du système. Une seule définition de type essai/capture manquante ou faible peut conduire à des pannes de serveur ou des bases de données corrompues. Pour relever ces défis, j'ai construit un moteur de production prêt à utiliser Express, TypeScript et Zod, une combinaison qui offre une sécurité et une flexibilité robustes.
L'arme contre la chaudière : asyncHandler HOC
Afin de lutter contre la nature répétitive des blocs d'essai et de prise manuellement autour de chaque gestionnaire de contrôleur, j'ai développé une fonction de commande supérieure asynchrone (HOC) nommée asyncHandler. Cette fonction gère automatiquement les erreurs en saisissant toutes les promesses rejetées et en les acheminant vers un gestionnaire d'erreurs centralisé. Voici comment ça marche :
importation { Request, Response, NextFunction, RequestHandler } de 'express'; export const asyncHandler = (fn: RequestHandler): RequestHandler => { retour (requête, res: Réponse, suivante: NextFunction) => { Promise.resolve(fn(req, res, next)) catch(next); }; };
Cette solution garantit que même avec une base de code importante, le traitement des erreurs reste cohérent et réduit la probabilité d'erreurs humaines. Au lieu d'encombrer les contrôleurs avec des blocs d'essai / prise, les développeurs peuvent se concentrer sur la logique d'affaires.
TypeScript Magic: Fusion de la déclaration pour la sécurité de type
Généralement, la coulée req comme n'importe quel pour accéder à des propriétés personnalisées comme userId ou requestId viole la sécurité du type. Pour maintenir une forte frappe sans recourir à de telles approches dangereuses, j'ai utilisé la fonction fusion de déclaration TypeScript. En étendant l'interface de demande interne d'Express et en fusionnant directement mes métadonnées personnalisées :
déclarer globale { espace de noms Express { demande d'interface { auth: { userId: number; email: string }; requestId: chaîne; validé?: { corps?: inconnu; question?: inconnu; params?: inconnu; }; } } }
Cette approche permet de garder le code propre et sûr, en veillant à ce que toutes les propriétés personnalisées soient correctement dactylographiées. Les .d.ts fichiers émis pendant la compilation fournissent la confiance de compilation-temps sans augmenter les frais généraux d'exécution.
Le pipeline de validation : les usines du Middleware avec Zod
Les API financières nécessitent souvent la validation de charges utiles importantes comme les paramètres de transaction ou les mises à jour. Placer la logique de validation dans les fonctions du contrôleur viole le principe de la séparation des préoccupations. Pour répondre à cela, j'ai créé un générique validate usine de middleware utilisant Zod:
importer { RequestHandler } de 'express'; Importer AppError à partir de './utils/AppError'; Type Source = 'params'
fonction d'exportation par défaut valide(schéma: T, source: Source): RequestHandler { retour (requête, res: Réponse, suivante: NextFunction) => { Const parsedValue = schema.safeParse(req[source]); si (!parsedValue.succès) { retour suivant(nouvelle AppError('Données de requête invalide', 400)); }
req.validated[schema.name] = parsedValue.data;
next();
}; }
Cette usine valide dynamiquement les charges utiles sur la base des schémas Zod et injecte les données validées dans le req.validated Objet. Les requêtes malformées sont automatiquement bloquées, garantissant que seules les entrées valides atteignent les contrôleurs backend.
Source : DEV Community. Synthèse éditoriale assistée par IA — TechnoExpress.

