Créer une API locale (self-hosted) avec Kestrel pour interagir avec une UI desktop

Comment créer une API REST hébergée localement sur la machine, ? En utilisant Kestrel, le serveur HTTP natif d’ASP.NET Core. Cette API sera alors accessible depuis n’importe quelle UI .NET : WinForms, WPF, MAUI, WinUI.

L’intérêt : découpler la logique métier/API de l’interface, tout en restant hors cloud.

🧱 Prérequis

  • .NET 9 SDK installé
  • Visual Studio 2022+
  • Aucune dépendance à IIS, Docker ou Azure

📁 Étape 1 – Création du projet API minimal

dotnet new webapi -n LocalApiDemo --no-https
cd LocalApiDemo

Supprimez tout sauf Program.cs. Créez une API minimale :

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/ping", () => "pong");
app.MapPost("/echo", (string message) => $"Vous avez dit : {message}");

app.Run("http://localhost:5005");

▶️ Lancer l'API localement

dotnet run

Naviguez sur http://localhost:5005/ping : vous verrez "pong".

Vous noterez que le numéro du port (ici 5005) n'est pas une valeur par défaut de Kestrel ni un nombre magique... Si vous regardez bien le code précédent, c'est dans app.Run(...) que l'on fixe le numéro du port. Il est donc possible de choisir n'importe quelle valeur disponible sur la machine, ou mieux, de lire cette valeur depuis un fichier de configuration simple ce qui permet de faire face tout conflit en changer le numéro sans avoir à recompiler l'appli serveur ni les applis utilisatrice (qui peuvent lire ce même fichier de configuration, en mode texte avec le numéro sur une ligne dans le cas le plus simple).

🖥️ Étape 2 – Appeler cette API depuis une app desktop

Exemple depuis une app WinUI / WPF / WinForms :

public async Task<string> InterrogerApi()
{
    using var client = new HttpClient();
    var response = await client.GetAsync("http://localhost:5005/ping");
    return await response.Content.ReadAsStringAsync();
}

Avec envoi d’une chaîne en POST :

public async Task<string> EnvoyerMessage(string message)
{
    using var client = new HttpClient();
    var content = new StringContent($"\"{message}\"", Encoding.UTF8, "application/json");
    var response = await client.PostAsync("http://localhost:5005/echo", content);
    return await response.Content.ReadAsStringAsync();
}

⚙️ Intégration possible avec une UI

<Button Content="Tester API" Click="OnClickTest" />
<TextBlock x:Name="ResultText" />

private async void OnClickTest(object sender, RoutedEventArgs e)
{
    ResultText.Text = await InterrogerApi();
}

💡 Bonnes pratiques

Bonne pratique

Pourquoi

Choisir un port fixe

Évite les conflits

Désactiver HTTPS en dev local

Plus simple

Restreindre au localhost

Sécurité

Documenter l’API avec Swagger

Test et debug visuel

🔒 Sécurité

Tant que votre API est restreinte à http://localhost, elle n’est pas exposée à l’extérieur. Cela en fait une option sécurisée pour une application de bureau.

Conclusion

Cette approche self-hosted avec Kestrel est idéale pour :

  • Utiliser un moteur IA local derrière une API
  • Factoriser la logique métier entre plusieurs interfaces
  • Simuler un serveur distant dans un environnement 100% local

.NET est bourré de possibilités incroyables. Il n'est pas toujours nécessaire de se compliquer la vie (et d'augmenter les coûts de production et de maintenance) en créant une usine à gaz sous ASP Core. Non pas que ce dernier ne soit pas une bonne solution, c'est un environnement fiable et robuste au contraire, mais parfois un peu lourd à manipuler pour des besoins simples qui peuvent se régler en quelques lignes de code comme on l'a vu ici. 

Faire simple, mais pas bâclé, en utilisant bien au contraire des méthodes modernes puisant leur puissance dans les capacités incroyables de .NET Core, c'est aussi une solution professionnelle parfaitement valide. Elle s'entourre de moins de blabla, de moins de concepts enrobés dans des discours grandiloquents, mais c'est pro, c'est moderne, ça marche, et ça ne coûte pas cher à mettre en place et à maintenir.

Faut-il utiliser systématiquement cette stratégie ? Ce n'est pas non plus ce que j'ai dit... il existe de nombreuses situations où cela est parfaitement inadapté. Dans ce cas on mettra en place une solution ASP Core sur un serveur dédié, bien équipé et géré par un admin rédeau. Mais on le sent bien, on change de catégorie et de montant sur la facture...

Stay Tuned !