Dans cet article, je vais vous présenter comment créer, configurer et tester un projetWebAPIen utilisantASP.NET Core 6.0etEntityFramework Core.
Introduction
UneAPIest uneinterface de programmation(en anglais Application Programming Interface) qui permet à plusieurs composants logiciels de communiquer, de s’échanger des données. UneAPImet à disposition une liste de ressources prédéfinies afin qu’elles soient utilisées par des applications tierces.
Par exemple, l’administration française permet d’accéder aux informations concernant les entreprises et les établissements immatriculés au répertoire inter administratif Sirene de l’Insee. Un simple appel à l’Api retournera les informations de dénomination, SIREN, SIRET, NAF, date de création et de clôture, …
Dans cette première partie, je vais créer le projet avec Visual Studio que je configurerai afin de générer les éléments nécessaires à la création d’une API.
Dans la seconde partie, je passerai à la création d’une API avec l’utilisation d’un contrôleur et d’une route.
Prérequis
Visual Studio 2019/2022 ;
.NET 6.0 SDK ;
SQL Server express ou autre.
Création du projet
Sur VisualStudio 2022 créer un nouveau projetAPI web ASP.NET Core
Définissez le nom et l’emplacement de votre projet puis suivant.
Afin de commencer un projet vide, décochez « Utiliser des contrôleurs » et veillez à bien sélectionner la version 6.0 du framework.
Schéma de base de données
Voici le schéma de base de données que je vais utiliser pour cet article. C’est une base de données avec simplement deux tables :
une tableUtilisateurs
une tableMétiers
Les utilisateurs peuvent être liés à un et un seul métier. Nous avons donc une référence du métier dans la table Utilisateurs.
Script de création des tables :
Voici le jeu de données que j’utilise :
Configuration & génération
Comme énoncé en introduction, j’utilise la méthodeDatabase-Firstdans le développement de cette application. Contrairement à l’approcheCode-First, où l’on commence par définir les modèles de données, avecDatabase-First, on commence par créer initialement la base de données.
Ensuite, à partir de cette base de données existante, j’utilise la commandeScaffold-DbContextfournie parEntity Frameworkpour générer automatiquement les classesC#correspondantes. Cela me permet de démarrer avec une base de données préexistante et de créer les modèles de donnéesC#associés de manière automatisée.
Afin d’utiliserDatabase-FirstavecEntityFramework, j’ai besoin des 2packagesci-dessous :
Microsoft.EntityFrameworkCore.SqlServer <= Provider SqlServer Microsoft.EntityFrameworkCore.Tools <= Active une liste de commandes dontScaffold-DbContext
Pour les installer, je vais utiliser laConsole duGestionnaire de Package : Outils => Gestionnaire de package NuGet => Console du gestionnaire de package
2. Ajout de la chaine de connexion
La commandeScaffold-DbContextprend en paramètre une chaine de connexion. Celle-ci doit être présente dans le fichierappsettings.json.
Voici la chaine de connexion :
Remplacez les informations en gras par :
SQLINSTANCE : Nom de votreinstanceSQL Server ;
DBNAME : Nom de votre base de données ;
USERNAME : Nom d’utilisateur ayant les droits sur votre base de données ;
USERPASSWORD : Mot de passe de l’utilisateur
Ci-dessous ma chaine de connexion avec mes informations :
Muni de votre chaine de connexion complétée, il faut ajouter une entrée « ConnectionStrings » dans le fichier appsettings.json avec votre chaine de connexion :
3. Utilisation de la commande Scaffold-DbContext
Voici la commande complète avec mes informations et mes paramètres :
Connectionqui cible le nom de votre chaine de connexion dans l’entrée ConnectionString de votre fichier appsettings.json (obligatoireetpositionnel);
Providerqui est généralement le nom du package de votre base de données. Par exemple si à la place d’une base SQL Server j’avais voulu utiliser une base PostgreSQL, il aurait fallu que je télécharge le packageNpgsql.EntityFrameworkCore.PostgreSQLet indiquer dans le provider le nom de ce package (obligatoireetpositionnel);
OutputDirle dossier de destination des dossiers générés (optionnel) ;
DataAnnotationsqui permet d’utiliser les attributs sur les modèles aux lieux de l’API Fluent (optionnel) ;
NoOnConfiguringqui supprime la méthode NoOnConfiguring lors de la génération (optionnel).
La commande est à exécuter dans la console du gestionnaire de package.
Attention, si votre projet ne compile pas correctement la commande s’exécutera en erreur.
Voici le dossier généré après exécution de la commande :
Dans ce dossier, nous retrouvons les classesMetier.csetUtilisateur.csqui sont les 2modèlescorrespondant auxtablesde ma base de données :
Metier.cs
Utilisateur.cs
Vous pouvez noter la présence du champ Utilisateurs qui est unecollection d’Utilisateursdans le modèleMetier.cs.
Si on suit notre schéma de base de données, ce champ ne devrait pas exister car, un Utilisateur sait à quel métier il est associé mais on ne sait pas quels sont les utilisateurs associés à un métier donné.
Ce champ a été créé car, EntityFramework utilise uneconvention de génération des navigations par défautbien spécifique en fonction du type de relation (un à plusieurs, plusieurs à plusieurs, un à un).
Ici, nous avons une relation de typeun à plusieurs : un utilisateur n’a qu’un seul métier et un métier correspond à plusieurs utilisateurs.
Ainsi, lorsqu’EntityFramework est face à une relation de type un à plusieurs, celui-ci l’a traduit par une relationbidirectionnelle : Un utilisateur sait à quel métier il est associé :
Et inversement, pour un métier donné, on sait les utilisateurs associés :
Cette Collection d’Utilisateurs posera des problèmes derécursivité.
Il faut ajouter l’attribut[JsonIgnore]pour indiquer à EntityFramework de ne plus sérialiser cette propriété, ce qui réglera ce problème de récursivité.
Et enfin, le dernier fichier généré est la classe la plus importante,WebAppContext.cs.Elle est responsable de toutes les interactions entre l’application et la base de données :
Création, transformation, exécution des requêtes ;
Gestion des transactions ;
Gestion de la concurrence ;
Gestion des relations ;
Suivi des modifications ;
Gérer les objets avec la base de données (MappingObject-Relationnel (ORM)) ;
…
En résumé, dès que je souhaite faire une action quelconque sur la base de données (rechercher des données, insérer des données, mettre à jour des modifications, activer une transaction …) je vais devoir passer par cette classe.
4. Ajout de dépendances
Afin de pouvoir faire des actions sur la base de données via la classe WebAppContext créée précédemment, il faut enregistrer cette classe dans le fournisseur de services d’application (conteneur d’injection). C’est ce qu’on appellel’injection de dépendance.
Dans la classeProgram.cs, j’ajoute l’injection de mon contexte viaAddDbContextjuste après la ligne var builder = WebApplication.CreateBuilder(args);
Puis, dans le contrôleur, je vais faire ce que l’on appelle del’injection de constructeurpour accéder à ma classe de contexte et enfin pouvoir communiquer avec ma base de données.
Je vais ajouter une deuxième dépendance dans le conteneur d’injection qui concerne les contrôleurs (AddControlleurs()). Ligne a ajouter après builder.Services.AddSwaggerGen();
Cette dépendance permet à l’application de savoir que je vais utiliser des contrôleurs. Sans cette dépendance il est impossible d’utiliser des contrôleurs dans mon application.
5. Suppression du code généré par défaut
Avant de créer le premier contrôleur, je supprime toujours le code généré par défaut à la création du projet pour d’avantage de lisibilité.
En effet, lors de la création du projet, celui-ci a créé automatiquement unendpointpar défaut en guise d’exemple.
Il se situe dans le programme de démarrage Program.cs :
💡
Ce bout de code créé un endpoint /weatherforecast qui va retourner une liste de données météos générées aléatoirement.
Il est en effet possible de créer desendpointsà partir de la classe de démarrage. Cela est pratique pour un petit projet avec peud’endpoints. Cependant pour des plus gros projets, il est indispensable de passer par des contrôleurs.
Supprimez le code ci-dessus du fichier Program.cs.
💡
Attention à ne pas supprimer par erreur la ligne app.Run(); qui se situe entre la déclaration du record WeartherForecast et l’Endpoint.
Conclusion
Nous avons appris, dans cette première partie à :
Créer un projet Visual Studio de type API
Configurer les accès à la base de données
Générer les classes correspondant aux tables de la base de données
Nous sommes désormais prêts à la création et la configuration d’un contrôleur et d’une route pour illustrer notre API.