Mini-API avec .NET 6
Si vous avez déjà utilisé ASP.NET MVC pour implémenter des API REST, vous avez probablement remarqué les nombreuses dépendances importées, la nécessité d’utiliser des contrôleurs ou encore la liste inutilement longue de fichiers juste pour développer un endpoint qui retourne une réponse en texte brut.
C’est là qu’entre en jeu les mini API d’ASP.NET Core, en proposant un code plus épuré tout en s’appuyant sur les concepts apportés par C# 10. Il est maintenant possible de réaliser rapidement des microservices en ASP.NET avec un minimum de dépendances et de fichiers.
Installation du SDK
Premier point important, vous devez disposer d’une version du SDK de .NET 6 sur votre poste. Vous pouvez la télécharger depuis le site de Microsoft en choisissant la version correspondant à votre OS.
Ou télécharger et installer Visual Studio 2022 qui inclus la dernière version du SDK. Cependant cette installation sera bien plus longue, Visual Studio étant loin d’être légère comme IDE. Idéalement vous pouvez passer par Visual Studio Code mais vous devrez installer le SDK au préalable sur votre poste ainsi qu’un module supportant le C# pour VSCode.
Pour être sûr que le SDK est correctement installé vous pouvez simplement vérifier la version avec la commande suivante depuis votre terminal favori :
dotnet --version
Utilisation des templates .NET
Il est temps de démarrer le développement de notre API avec .NET 6. Depuis la CLI fournie par le SDK .NET, Microsoft propose des templates de création que vous pouvez lister de la manière suivante :
dotnet new -l
La liste (allégée) ci-dessous devrait vous être proposée :
Ces modèles correspondent à votre entrée : .
Nom du modèle Nom court Langue Balises
-------------------------------------------- ------------------- ---------- ------------------------
Application console console [C#],F#,VB Common/Console
Application Windows Forms winforms [C#],VB Common/WinForms
Application WPF wpf [C#],VB Common/WPF
ASP.NET Core Empty web [C#],F# Web/Empty
ASP.NET Core gRPC Service grpc [C#] Web/gRPC
ASP.NET Core Web API webapi [C#],F# Web/WebAPI
ASP.NET Core Web App razor,webapp [C#] Web/MVC/Razor Pages
ASP.NET Core Web App (Model-View-Controller) mvc [C#],F# Web/MVC
ASP.NET Core with Angular angular [C#] Web/MVC/SPA
ASP.NET Core with React.js react [C#] Web/MVC/SPA
ASP.NET Core with React.js and Redux reactredux [C#] Web/MVC/SPA
...
Si vous utilisez Visual Studio 2022, vous aurez accès à cette même liste depuis la création d’un nouveau projet.
On remarque dans la liste la présence de la template ASP.NET Core Web API. C’est la template par défaut pour créer une API REST. Si vous utilisez cette template, celle-ci apportera un exemple de contrôleur avec un endpoint par défaut, un modèle de données et une implémentation de Swagger configurée pour être utilisable depuis un environnement de développement. Mais ce modèle reste encore assez proche de ce que l’on trouve sous ASP.NET MVC avec la présence de nombreux fichiers.
Je vous invite donc à utiliser une template vide via la commande suivante :
dotnet new web -o mini-api
Le paramètre o
indique où votre projet d’API doit être installé, ici en l’occurrence dans le dossier mini-api
. Si vous ouvrez le dossier mini-api
, vous remarquerez la présence du fichier Program.cs
qui est le point d’entrée de votre API. Celui-ci contient le code suivant :
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
Il est intéressant de noter que l’initialisation est allégée par l’utilisation d’un builder
par lequel on va pouvoir ajouter des services, des paramétrages ou des environnements. Il n’y a plus de fichier Global.asax
ou Web.config
.
Remarquez d’ailleurs l’absence d’espace de nom ou de classe program
dans le fichier Program.cs
. C’est l’une des nouveautés de C# 9 pour alléger l’écriture du code. On est finalement plus proche d’un script Node.js que devant un programme C# classique.
Vous pouvez démarrer en l’état votre API avec la commande :
dotnet run
Un fichier de configuration est disponible depuis le dossier Properties
. C’est dans le fichier launchSettings.json
qui vous allez pouvoir paramétrer votre serveur Web local. Un port est généré aléatoirement à la création de la template. Libre à vous de le modifier depuis la propriété profiles.mini_api.applicationURL
et d’utiliser celui que vous souhaitez. Il n’est d’ailleurs pas nécessaire de conserver l’URL en https
, mais il est intéressant de noter que .NET prends en charge nativement le protocole.
Si vous utilisez une autre IDE que Visual Studio 2022, une limitation de la CLI empêche l’utilisation de certains paramètres comme l’ouverture d’un navigateur à l’exécution : launchBrowser
.
Reste plus qu’à lancer un navigateur et ouvrir l’URL fournit par le fichier launchSettings.json
. Vous devriez avoir un beau Hello World!
en guise de réponse.
Installer et utiliser une dépendance
On va aller un petit peu plus loin dans la création de notre API et faire en sorte que notre endpoint retourne des informations récupérées depuis une base de données. Pour notre exemple on va passer par une base Sqlite3 fictive qui contiendrait une table Users.
Si vous êtes sous Visual Studio 2022, il vous suffit de passer par le gestionnaire de paquets NuGet et d’aller rechercher le composant Microsoft.Data.Sqlite
. Dans le cas contraire il suffit d’utiliser la commande ci-dessous :
dotnet add package Microsoft.Data.Sqlite --version 6.0.1
Si tout s’est bien passé, vous devriez avoir la ligne suivante dans les dépendances du projet située dans le fichier min-api.csproj
:
<ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.1" />
</ItemGroup>
Reste plus qu’à importer la dépendance dans notre fichier Program.cs
et à l’utiliser pour requêter notre base fictive. Nous allons également utiliser un objet DataTable
pour stocker le résultat de notre requête. Cela nous évitera de parser le résultat, .NET s’en chargera pour nous. Il convient d’importer également le paquet dans notre programme.
using Microsoft.Data.Sqlite;
using System.Data;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => {
var connectionStringBuilder = new SqliteConnectionStringBuilder() {
DataSource = "c:/sqlite3/myDB.db"
};
using (var connection = new SqliteConnection(connectionStringBuilder.ConnectionString)) {
connection.Open();
var selectCmd = connection.CreateCommand();
selectCmd.CommandText = "SELECT * FROM Users;";
DataTable dt = new DataTable();
using (var reader = selectCmd.ExecuteReader())
{
dt.Load(reader);
}
return dt;
}
});
app.Run();
Concrètement on pourrait se dire que tout est ok pour lancer notre API. Mais il y a un mais. .NET n’est pas capable de sérialiser la DataTable
en l’état. Si vous tentez d’appeler le endpoint vous aurez droit à une belle exception de non prise en charge.
Heureusement il existe des composants qui le font très bien :
dotnet add package Newtonsoft.Json --version 13.0.1
Il suffit ensuite de modifier le fichier Program.cs
de cette manière :
using Microsoft.Data.Sqlite;
using System.Data;
using Newtonsoft.Json;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => {
var connectionStringBuilder = new SqliteConnectionStringBuilder() {
DataSource = "c:/sqlite3/myDB.db"
};
using (var connection = new SqliteConnection(connectionStringBuilder.ConnectionString)) {
connection.Open();
var selectCmd = connection.CreateCommand();
selectCmd.CommandText = "SELECT * FROM Users;";
DataTable dt = new DataTable();
using (var reader = selectCmd.ExecuteReader())
{
dt.Load(reader);
}
return JsonConvert.SerializeObject(dt);
}
});
app.Run();
Cette fois plus de problème lors de l’appel du endpoint.
CORS
Si vous souhaitez que votre endpoint soit accessible depuis n’importe quel site Web, il va falloir ajouter une configuration CORS à votre API afin d’accepter les appels Cross-Domain. Il suffit d’utiliser les services offerts par le builder
pour ajouter très facilement cette configuration.
...
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(opt => opt.AddDefaultPolicy(policy => policy.AllowAnyOrigin()));
var app = builder.Build();
...
Faites bien attention d’ajouter la configuration après l’initialisation du builder
.
Pour terminer l’ajout des CORS, il ne faut pas oublier de les exécuter sur votre API. Ajouter simplement cette commande à la fin de votre fichier :
...
app.UseCors();
app.Run();
Conclusion
Dans cet article nous avons vu comme développer une Mini-API à l’aide de la version 6 du Framework .NET, et qu’il est tout à fait possible de produire une API avec un minimum de code dans la même veine que les API produites sous Node.js. Bien sûr rien ne vous empêche d’ajouter de la logique supplémentaire et de tirer partie des ressources offertes par le Framework .NET.
Références
- Code source de l’article sur GitHub : https://github.com/GutsFun/Mini-API-with-DotNet6
- Cross-origin resource sharing (CORS) : https://developer.mozilla.org/fr/docs/Web/HTTP/CORS
- Installation du SDK .NET 6 : https://dotnet.microsoft.com/en-us/download/dotnet/6.0
- Site officiel Sqlite : https://www.sqlite.org/