Fermer

septembre 25, 2024

Meilleures pratiques pour la création de projets d’API ASP.NET Core

Meilleures pratiques pour la création de projets d’API ASP.NET Core


À bien des égards, les meilleures pratiques pour un backend ASP.NET Core sont les mêmes que pour toute autre application que vous créez. Mais il existe certaines bonnes pratiques qui résolvent des problèmes propres à la structuration des projets API (et même aux projets ASP.NET Core).

À mesure que l’univers du développement Web s’oriente de plus en plus vers le développement côté client, vous devez commencer à accorder plus d’attention à la façon dont vous configurez votre backend API. Heureusement, comme pour d’autres développements d’applications, l’application du Des principes SOLIDES et le approprié modèles de conception vous donnez le meilleur de vous-même pour créer un backend avec lequel vous vivez… du moins, où les backends d’API sont similaires à d’autres types d’applications.

Cependant, il existe certains domaines dans lesquels les projets d’API et, en particulier, les projets d’API ASP.NET Core sont différents des autres types d’applications. Voici quelques bonnes pratiques dans ces domaines.

API minimales par rapport aux APIControllers

Votre première décision lors de la création d’un backend d’API avec ASP.NET Core consiste à décider si vous utiliserez Classes de contrôleur API ou API minimales.

Il y a beaucoup à dire sur les fonctionnalités fournies par les classes de contrôleurs API : liaison de modèle, routage basé sur des paramètres, validation de modèle et bien plus encore : tout ce que vous n’avez pas besoin de créer. De plus, si vous avez de l’expérience dans la création de contrôleurs MVC, les contrôleurs API vous sembleront très familiers, vous permettant de commencer à développer des fonctionnalités plus rapidement que de passer à une nouvelle technologie (c’est-à-dire des API minimales). Les classes de contrôleur API prennent également en charge les parties d’application d’ASP.NET Core, ce qui vous permet d’éviter de charger l’intégralité de l’application lorsque seule une partie de celle-ci est nécessaire.

Mais cela dit, les API minimales sont plus faciles à écrire que les classes de contrôleurs d’API : commencez simplement à ajouter du code dans Program.cs et vous avez créé votre API. Avec un minimum d’API, votre projet backend pourrait avoir un seul fichier de code : Program.cs. De plus, des API minimales vous offrent des options autour gestion des itinéraires via la méthode MapGroup qui ne sont pas disponibles dans les classes de contrôleur. Sauf si vous avez une raison impérieuse d’utiliser les APIControllers (par exemple, tirer parti de l’expérience avec les contrôleurs MVC, tirer parti des classes de modèles existantes avec prise en charge de la validation des données), vous souhaitez utiliser un minimum d’API.

La meilleure pratique ici consiste à trouver des moyens d’éviter les ballonnements dans votre fichier Program.cs. Si vous créez un service simple avec un ensemble de fonctionnalités très ciblé et limité (un service de licence, par exemple), avoir tout votre code dans Program.cs peut être une approche raisonnable. Cependant, pour les applications plus volumineuses, la gestion de la taille de votre fichier Program.cs devient un problème : si vous n’y faites pas attention, les membres de l’équipe finiront par se battre pour savoir qui pourra extraire Program.cs et le résultat des fusions deviendra… intéressant. .

Il existe une variété de stratégies pour gérer le gonflement de Program.cs. Vous pouvez déplacer le corps de vos méthodes API hors de Program.cs en appelant des méthodes sur les classes instancié dans le code Program.cs ou par appeler des méthodes statiques sur les classes dans vos méthodes API.

Vous pouvez également diviser Program.cs en plusieurs fichiers en le configurant comme une classe partielle avec vos définitions d’API minimales dans l’un des fichiers de classe partielle. Une autre option (ma préférée) consiste à transmettre l’objet Application Builder de Program.cs à une méthode (ou des méthodes) dans un fichier en dehors de Program.cs et à y définir vos méthodes API minimales.

La meilleure pratique ici n’est pas la stratégie que vous choisissez, mais d’en choisir une et de l’appliquer tôt dans la vie de votre projet avant que votre fichier Program.cs ne devienne incontrôlable.

Votre « Expérience Client » externe

En général, les applications peuvent être considérées comme un moyen de convertir les ressources backend (par exemple, la table clients, la table des commandes clients et la table produits de votre base de données) en une expérience utilisateur cohérente (la page de mise à jour des commandes clients). Il en va de même pour vos services.

Sur le plan logistique, vous souhaiterez organiser vos services autour des départements de votre organisation afin (par exemple) de simplifier le financement, d’affecter des équipes de support et de gérer les parties prenantes impliquées dans la décision sur l’évolution de votre service. Techniquement, vous souhaiterez structurer vos projets API en utilisant les principes SOLID, la séparation des préoccupations, etc.

Bien entendu, rien de tout cela n’a d’importance pour les clients qui accéderont à votre service et, si vous n’y faites pas attention, une transaction client typique devra passer par plusieurs services. La transaction « achat d’un produit », par exemple, peut nécessiter qu’un client intègre des services répartis entre les services de vente, d’inventaire, d’entrepôt, d’expédition et de comptes clients.

Vos clients voudront plutôt pouvoir envoyer une demande à un seul point de terminaison pour effectuer ce que le client considère comme une transaction unique. Vous devrez distribuer cette requête unique sur les multiples services que vous avez créés pour prendre en charge cette requête (et, occasionnellement, pour faire la chose « atypique », les clients devront accéder directement à ces services individuels).

Pour gérer cela, vous avez besoin d’un frontal de façade pour votre API (quelque chose comme Gestion des API Azure). Si la façade que vous utilisez ne prend pas en charge l’orchestration (la distribution d’une requête unique sur plusieurs services backend), vous devez alors soit écrire vos propres orchestrateurs spécifiques à la requête, soit acheter un outil tiers.

Normalement, je suis un grand fan des outils tiers car ils me permettent de me concentrer sur les fonctionnalités propres à mon application. Cependant, en l’absence d’orchestrateur, écrire votre propre orchestrateur spécifique à une requête n’est pas une mauvaise pratique (et peut même être considéré comme une bonne pratique).

La création d’un orchestrateur spécifique à une requête ne devrait pas représenter un effort majeur, à condition que vous le gardiez concentré sur une transaction spécifique (c’est-à-dire, n’essayez pas de faire évoluer l’orchestrateur conçu pour gérer « l’achat d’un produit » vers un outil à usage général). En fait, si l’orchestrateur d’une transaction n’est pas simple (s’il ne se contente pas de transmettre des requêtes et des parties d’un message à différents services), c’est le signe que votre architecture de service rencontre des problèmes.

La structure interne de votre projet

Le backend de votre API évoluera et changera au fil du temps. Lorsque vous améliorez le backend de votre API, demandez-vous toujours si un nouveau code appartient à un projet existant ou devrait être le point de départ d’un nouveau projet.

N’oubliez pas que dans ASP.NET, vous êtes pas Il est nécessaire d’avoir tout le code de n’importe quel point de terminaison dans le même projet (et l’inverse est également vrai : le code de différents points de terminaison peut être dans le même projet). Vous devez réfléchir à la manière dont la responsabilité de la maintenance/du financement de ce code sera répartie entre les équipes et les départements et structurer vos projets pour prendre en charge cela.

À mesure que les services évoluent, il peut être judicieux de créer deux projets à partir d’un projet existant (généralement parce qu’un projet devient trop important pour son équipe ou viole le principe de responsabilité unique ou la séparation des préoccupations). Cette division sera généralement gérée en répartissant les fonctionnalités de l’API sur deux projets ou plus.

La meilleure pratique ici consiste à organiser le code dans votre projet API par fonctionnalités afin de faciliter la distribution de votre code sur de nouveaux projets. S’il existe plusieurs équipes prenant en charge un seul projet d’API (ce qui peut indiquer qu’il est temps de diviser le projet), chaque équipe sera généralement responsable de différentes fonctionnalités. Par conséquent, les dossiers de votre projet doivent contenir le code unique de chacune des fonctionnalités de votre API (qui peut ou non correspondre à vos points de terminaison) ; les ressources du projet partagées par plusieurs fonctionnalités (par exemple, classes de base ou classes d’assistance) doivent se trouver dans leurs propres dossiers.

Services de gestion de versions

Lorsque vous ajoutez ou supprimez des fonctionnalités des services derrière un point de terminaison, il y aura souvent une période de temps pendant laquelle l’ancienne et la nouvelle version d’un service devront être disponibles. Cela peut être permanent (pour prendre en charge les clients qui ne souhaitent pas accéder aux fonctionnalités supplémentaires de la nouvelle version) ou à court terme (pour prendre en charge une période de migration). Pendant cette période, vous devez prendre en charge le contrôle de version afin que les clients puissent choisir la version du service qu’ils souhaitent.

Vous disposez d’options ici : vous pouvez incorporer des informations de version dans l’URL du point de terminaison (par exemple, …/v1/customers vs. …/v2/customers), dans la chaîne de requête du point de terminaison (par exemple, …/customers?v=1 vs. …/customers). ?v=2), ou dans un en-tête (la version X-API est provisoirement enregistrée à cet effet depuis 2005).

Il n’y a pas de bonne réponse généralement acceptée ici. Personnellement, je pense que l’intégration des informations de version dans l’URL viole la convention selon laquelle les points de terminaison sont cohérents dans le temps. En conséquence, je préfère utiliser les stratégies de chaîne de requête ou d’en-tête. Vous prendrez votre propre décision. Vos clients conservent probablement les URL de votre point de terminaison dans des fichiers de configuration faciles à mettre à jour. La modification des URL n’est donc pas une tâche onéreuse pour les clients tant que les informations de version précèdent les valeurs de paramètre dans l’URL. Après tout, le véritable effort des clients consiste à restructurer les messages et à tirer parti des nouvelles fonctionnalités.

Quelle que soit la stratégie que vous choisissez, la meilleure pratique consiste ici à exploiter le package ASP.Versioning.Http NuGet dans ASP.NET Core pour implémenter le contrôle de version. Ce package ajoute l’extension AddApiVersioning à l’objet Services qui, à son tour, vous permet de spécifier ApiVersioningOptions dans Program.cs. Par défaut, le package s’attend à ce que les informations de version soient dans la chaîne de requête, mais l’ajout de la prise en charge de la lecture d’un en-tête est simple (et le package prend également en charge la gestion des versions de l’URL, si vous insistez). Si vous utilisez Swagger, vous souhaiterez également ajouter le package Asp.Versioning.Mvc.ApiExplorer.

En fait, lier votre code à une version est géré différemment dans les API minimales et dans les APIControllers :Milan Jovanovic a une excellente discussion sur les options avec le code nécessaire.

Cette liste n’est pas exhaustive (autres bonnes pratiques : documentez votre API, utiliser JSON et plus). Mais si vous mettez en œuvre ces pratiques, vous aurez une meilleure chance de créer un backend d’API avec lequel vous pourrez vivre (du moins, sans plus de douleur que ce qui est absolument nécessaire).




Source link