Accueil > Minimal API dans ASP.NET Core
Sylvain Sidambarom
10 novembre 2022

Minimal API dans ASP.NET Core

Minimal API dans ASP.NET Core

Les minimal APIs sont sorties en même temps que .NET 6, C# 10 et de nombreuses améliorations de performance. Mais en quoi consistent-elles exactement et comment se mettent-elles en place ? C’est que nous vous proposons de voir ensemble dans cet article à l’occasion de la sortie de .NET 7 et de l’annonce de nouvelles améliorations.

 

Qu’est-ce qu’une minimal API ?

 

Le concept de minimal API est présenté comme une alternative au Controller d’ASP.NET Core pour définir une API avec le minimum de dépendances. Elle semble être la réponse de Microsoft aux APIs définies sur NodeJS (via ExpressJS).

Regardons en détail le cas d’une API standard en NodeJS :

 

Le code ci-dessus définit, de façon standard, un Endpoint GET qui retourne la liste des plateformes supportées par un serveur NodeJS. On y trouve également la déclaration du port écouté par le serveur (ici 3000).

La réponse de cette API est la suivante :

["Windows","Mac","Linux","Unix"]

 

Essayons d’en faire de même avec la minimal API d’ASP.NET Core.

 

Création du premier Endpoint

 

Pour créer notre première minimal API, nous allons créer un projet ASP.NET Core vide via cette commande :

Dotnet new web -n MyMinimalAPI

 

Cette dernière va créer un projet web avec le minimum de dépendances, dont le Program.cs est le suivant :

 

Une fois l’application lancée, nous avons bien le message « Hello World ! » qui apparaît sur notre navigateur.

Rentrons dans le détail pour comprendre ce qui se cache derrière ces 4 lignes de code.

La première chose qui devrait vous sauter aux yeux est l’absence de « using » au début du fichier. Cela est dû au fait qu’en C# 10 a été introduite la notion de global using. Cette fonctionnalité permet de déclarer des « using » qui sont considérés comme présents dans tous les fichiers du projet. Par défaut cette fonctionnalité est activée grâce à la clé « ImplicitUsings » présente dans le csproj.

 

Vous trouverez ci-dessous la liste des « usings » globaux par défaut définis dans le « template ». On y trouve le namespace « Microsoft.AspNetCore.Builder » où est définie la méthode MapGet().

 

Voici à présent la méthode MapGet dont les signatures sont les suivantes :

 

Elles acceptent un délégué en troisième paramètre, nous pouvons ainsi passer n’importe quelle méthode et le compilateur se chargera de convertir notre délégué en « RequestDelegate » s’il le peut.

Enfin,  « app.Run()» permet de lancer l’application.

L’équivalent de notre API en NodeJS est le suivant :

 

La propriété Urls permet de déclarer les ports à écouter.

 

Routing

 

Le routing de chaque endpoint se déclare de façon explicite. Dans l’exemple précédent, la route du endpoint était « /my-supported-platforms ». Cette route n’a pas de variable, mais peut être modifiée dans ce sens :

 

Ci-dessus, nous avons défini un nouvel Endpoint qui retourne une plateforme spécifique en passant l’identifiant de la plateforme choisie.

 

Injection de dépendance

 

Une nouvelle fonctionnalité du gestionnaire de dépendance lui permet de savoir quels types sont enregistrés et retrouvables depuis son conteneur. Dès lors, il n’est plus nécessaire d’utiliser un attribut pour déclarer qu’un type vient du conteneur de gestion dépendance.

Dans le cas d’une minimal API, nous pouvons injecter nos dépendances de la façon suivante :

 

Ici, notre Endpoint dépend de deux paramètres, ASP.NET est suffisamment intelligent pour savoir où retrouver les dépendances. Toutefois, si vous lancez le projet avec cette modification, vous obtiendrez l’erreur suivante :

Erreur si on souhaite retrouver les dépendances de notre Endpoint

 

Cette erreur est due au fait qu’ASP.NET Core n’a pas trouvé au moins une des dépendances de l’Endpoint. Ici l’ « IHppClientFactory » n’étant pas enregistré dans le gestionnaire de dépendances, ASP.NET Core tente de retrouver la factory dans le corps de la requête sans succès.

Pour corriger cette erreur, il vous suffit d’ajouter à votre gestionnaire de dépendances le type manquant, comme suit :

 

La méthode AddHttpClient va ajouter « IHttpClientFactory » dans le gestionnaire de dépendances, rendant ainsi ce dernier retrouvable.

 

Déclaration des différents verbes

 

La minimal API expose des méthodes dédiées pour les verbes POST, PUT et DELETE comme suit :

  • MapPost()
  • MapPut()
  • MapDelete()

Les signatures de ces méthodes sont identiques à celle de la méthode « MapGet ».

 

Mise en pratique de minimal API

 

Appliquons ce que nous venons de voir sur un cas concret. Nous allons créer une application de gestion de livres qui contient les fonctionnalités du CRUD (Create, Read, Update, Delete) :

  • Récupérer tous les livres
  • Récupérer les détails d’un livre
  • Créer un nouveau livre
  • Mettre à jour un livre
  • Supprimer un livre

 

Modèle et cas d’usage basique

 

Le modèle de données que nous avons choisi pour cet exemple est le suivant :

Modèle et cas d'usage basique

 

 

Nous utiliserons « Entity Framework Core » avec « Sqlite » pour persister et manipuler nos données. A la racine de notre projet, nous installons les packages nuget suivants :

 

Le premier nous sert à interagir avec nos données, tandis que le second nous permet d’initialiser notre base de données à partir du code suivant :

 

L’initialisation de notre base de données et le « context » associé se fait via ce code dans Program.cs :

builder.Services.AddDbContext<MyDbContext>();

 

 

Endpoint de lecture (Read)

 

Ecrivons nos premiers Endpoints qui permettent de :

  • Récupérer tous les livres
  • Récupérer le détail d’un livre.

 

 

Comme nous l’avons vu précédemment, le gestionnaire de dépendances retrouve le « dbContext » et l’injecte dans notre délégué.

Vous remarquerez que pour retourner le résultat, nous utilisons les méthodes de la classe « Results » du namespace « Microsoft.AspNetCore.Http ». Cette dernière expose un grand nombre de types de réponse HTTP. Pour plus de détails, je vous invite à visiter la page GitHub de la classe.

 

Création (Create), Mise à jour (Update) et Suppression (Delete)

 

Forts de notre expérience avec la lecture des données, attaquons-nous maintenant à la création, la mise à jour et la suppression qui adoptent la même approche.

 

La mise à jour est similaire à la création, à la différence que l’on passe l’identifiant du livre que l’on veut modifier.

 

Enfin, la suppression se présente comme ci-dessous :

 

Intégration de Swagger

 

La minimal API supporte les spécifications de l’Open API via Swashbuckle.

 

  1. Installons le swashbuckler dans notre projet
dotnet add package Swashbuckle.AspNetCore

 

  1. Injectons les services nécessaires au fonctionnement de Swagger
builder.Services.AddEndpointsApiExplorer();

builder.Services.AddSwaggerGen();

 

  1. Ajoutons l’interface UI de Swagger dans le middleware ASP.NET Core
    app.UseSwagger();

    app.UseSwaggerUI();
  1. Compilons et lançons le projet sur l’endpoint de Swagger : /swagger/index.html

 

Minial Project

 

Tous nos Endpoints définis plus tôt sont présents. Il est cependant possible de faire mieux en enrichissant la description des Endpoints comme le montre les exemples ci-dessous :

 

NET. 6 a introduit des méthodes d’extensions qui permettent l’enrichissement la définition des Endpoints :

  • Produces : décrit le type de ressources retourné par le Endpoint et le statut de la réponse
  • WithName: Identifiant unique d’un Endpoint
  • WithTags: Nom de la catégorie d’un Endpoint

 

Minial Project 2

 

Les Endpoints sont regroupés dans les catégories que nous avons définies précédemment.

 

Minimal API : l’essentiel à retenir

 

Minimal API est un nouvel outil à disposition des développeurs pour créer des APIs rapidement, sans toute la stack MCV ou Web API d’ASP.NET Core.

Nous avons vu combien la mise en place des minimal APIs dans un projet web est simple, au travers d’un cas concret de CRUD. Nous avons ensuite constaté comment ASP.NET Core permet de gérer les dépendances des Endpoints avec peu de code dans la mesure où il est capable de déduire où récupérer les dépendances.

Vous trouverez le code source de cet article ici.

 

Pour approfondir vos connaissances, nous vous invitons à consulter la documentation suivante :

 

Et pour en savoir plus sur les dernières nouveautés de .NET 7, n’hésitez pas à consulter les autres articles de cette série :

 

Nos autres articles
Commentaires
Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Restez au courant des dernières actualités !
Le meilleur de l’actualité sur le Cloud, le DevOps, l’IT directement dans votre boîte mail.