Introduction

Dans un précédent article nous avions parlé de Swagger et comment celui-ci définit un standard pour la description des services RESTindépendamment de la plateforme. Avec Swagger, un ensemble de spécifications doivent être respectées. Ainsi du contenu JSON doit être accessible sur le serveur hébergeant le service REST. Ce fichier JSON contient la définition Swagger c’est à dire les métadonnées de notre service. Un certain nombre d’outils ont été créés par la communauté de développeurs pour permettre de générer une classe Proxy côté Client en se basant sur ces métadonnées. Cette classe Proxy a pour but de simplifier le code permettant la communication entre l’application client et le serveur. Avec la technologie ASP.NET Web API, si le service dispose d’une définition Swagger alors nous pouvons utiliser l’outil AutoRest créé par l’équipe Azure pour générer notre classe proxy. Il faut noter que Swagger est utilisé dans les Azure API Apps. Cependant pas besoin d’héberger son service REST sur cette plateforme encore moins créer une API App pour pouvoir bénéficier des fonctions offertes par AutoRest.

Installation de l’outil AutoRest

L’installation peut se faire de deux manières via NuGet ou via Chocolatey. L’image ci-dessous montre l’installation via Chocolatey en utilisant la commande “choco install AutoRest”. Au moment de la rédaction de cet article, la version approuvée par l’équipe Chocolatey est la version “0.9.7” alors que nous en sommes à la version “0.10.0” (version disponible sur NuGet). La ligne de commande précitée installe la dernière version approuvée, j’ai dû spécifier la version “0.10.0” comme valeur de l’option“-version” comme dans l’image ci-dessous :

installation AutoRest

Une fois l’installation terminée, pour vérifier que tout a été bien configuré, il suffit, en ligne de commande, de taper “AutoRest” pour voir s’afficher l’aide de l’outil. Si tel n’est pas et que l’installation de AutoRest s’est bien déroulée alors il faudra vérifier que le chemin vers le fichier exécutable “AutoRest. exe” est bien défini dans les variables d’environnement de votre ordinateur.

AutoRest en ligne de commande

Avant tout, le service ASP.NET Web API utilisé comme cas exemple de cet article contient un seul contrôleur avec les actions définies comme suit :

ligne de commande

Comme dit dans l’introduction, le service ASP.NET Web API doit disposer d’une définition Swagger pour que AutoRest puisse générer la classe proxy. Si vous avez utilisé le package Swashbuckle (dont l’utilisation est expliquée dans cet article) pour exposer les métadonnées Swagger de votre service alors le contenu JSON est accessible via l’URL relative suivante : “swagger/docs/v1”. Vous devez enregistrer le contenu JSON dans un fichier “Swagger. json” à la racine de votre projet client par exemple.

La définition Swagger du service ASP.NET Web API exemple est la suivante :

Swagger de ASP.NET Web API

Nous pouvons exécuter la ligne de commande ci-dessous :

exécution ligne de commande

AutoRest va créer un dossier “Generated” contenant le code généré. Il faudra inclure ce dossier dans le projet Visual Studio de votre application client. Il faut noter que la compilation du projet ne marchera pas tant que le package Client Runtime Library (Microsoft.Rest.ClientRuntime) n’est pas installé. Cela est nécessaire parce que la classe Proxy dérive de la classe abstraite “ServiceClient<T>” dont l’implémentation se trouve dans la librairie fournie par ce package NuGet.

Nous avons utilisé deux options “Input” et “Namespace” qui permettent respectivement de spécifier le chemin vers le fichier JSON (celui contenant la définition Swagger) et l’espace de nom à utiliser pour les classes générées. Les différentes options possibles en ligne de commande pour AutoRest sont les suivantes :

  • “OutputDirectory” : permet de spécifier dans quel dossier les classes (Proxy et autres) seront générées. Par défaut elles sont dans un dossier nommé “Generated”.
  • “ClientName” : par défaut le nom du proxy généré sera le titre contenu dans le propriété “info” de notre définition Swagger avec tous les espaces et caractères spéciaux retirés. Cette option est nécessaire si nous voulons donner un nom plus parlant à la classe faisant office de proxy.
  • “AddCredentials” : avec cette option, quelques modifications seront ajoutées au code généré pour simplifier le code permettant d’authentifier le client auprès du service web.
  • “OutputFileName” : les classes générées sont définies dans des fichiers séparés par défaut. Si vous voulez générer un seul et unique fichier contenant tout le code (je ne recommande pas cette façon de faire) alors cette option permet de renseigner le nom du fichier de destination.
  • “CodeGenerator” : par défaut, AutoRest utilise C# comme langage de programmation pour le code généré. Cette option nous permet d’utiliser un autre générateur et les différents générateurs possible avec la version “0.10.0” utilisée dans cet article sont uniquement NodeJS et CSharp.
  • “Modeler” : le seul modeleur actuellement utilisable avec AutoRest reste Swagger 🙂
  • “Header” : permet de spécifier le texte à insérer eu début de chaque fichier généré. Par défaut le texte inséré est le suivant :
    /// Code generated by Microsoft (R) AutoRest Code Generator 0.10.0.0
    /// Changes may cause incorrect behavior and will be lost if the code is regenerated.
    

Dans le cas d’une application .NET, les 3 premières options seront actuellement les plus utiles à retenir. Pour notre service web exemple aucune authentification n’est requise ainsi, pour la suite de l’article, la ligne de commande suivante a été utilisée pour générer le proxy nommé MyWebServiceClientdans le dossier WebServiceProxies et l’espace de nom des classes générées est WebApiClientApp. WebServiceProxies:

 WebApiClientApp. WebServiceProxies:

AutoRest via Visual Studio

Comme dit dans l’introduction, c’est l’équipe Microsoft Azure qui a développé l’outil AutoRest pour les besoins des Azure API Apps puisque celles-ci utilisent Swagger pour exposer leurs métadonnées. Cela ne nous empêche pas d’utiliser AutoRest en dehors d’Azure en l’installant via NuGet ou Chocolatey puis l’utiliser en ligne de commande comme expliqué dans la précédente section. Cependant si vous être allergique à la ligne de de commande alors l’équipe Azure a développé des outils pour nous faciliter l’utilisation au sein de Visual Studio. Pour cela, il faut au minimum installer la version “2.6” du SDK Azure. L’installation prendra quelques minutes et cela va inclure tous les autres outils Azure dont on n’a pas besoin. C’est le prix à payer pour pouvoir utiliser l’interface graphique de génération de proxy avec AutoRest même si votre application n’est aucunement liée à cette plateforme.

autorest dans visual studio

Après l’installation, il faut tout simplement faire un clic droit sur le projet de l’application Client, puis le menu “Ajouter” et cliquer sur le menu “Client Azure API App”. Une nouvelle fenêtre s’ouvre et se présente comme suit :

ajouter

Vous devez sélectionner l’option permettant de spécifier le fichier contenant la définition Swagger, puis saisissez l’espace de nom dans lequel doivent être définies les classes générées et valider. La fenêtre “Activité du service Azure App” s’ouvre et vous affiche les différentes étapes de la génération du code :

activités du service Azure App

Je préfère de loin la ligne de commande par rapport à l’interface graphique. Bien que ce dernier installe automatiquement le package NuGet “Microsoft. Rest. ClientRuntime”, l’interface n’intègre pas pour le moment les options comme le choix du nom du dossier dans lequel sera mis le code généré et la configuration du nom de la classe Proxy.

Utilisation du proxy

Les fichiers générés par AutoRest, pour notre service web exemple, sont affichés dans l’image ci-dessous :

utilisation du proxy

Notre service exemple contient un seul contrôleur et les 3 fichiers “IValues”, “Values” et “ValuesExtensions” ont été générés pour ce contrôleur. Ces trois types de fichier existeront autant de fois qu’il y a de contrôleurs définis au niveau de notre service. Dans mon cas, “IValues” contient les contrats représentés par des méthodes associées à chacune des opérations exposées par le service web, qui sont donc définies dans le fichier de métadonnées “Swagger. json”. La classe “Values” implémente l’interface “IValues” et les méthodes qu’elle implémente ont toutes le type de retour “Task<HttpOperationResponse>” ou “Task<HttpOperationResponse<T>>”. Pour nous faciliter encore plus la tâche, la classe “ValuesExtensions” contient des méthodes d’extensions encapsulant celles définies dans “Values” afin que le code côté client soit encore plus simple à écrire. Ces méthodes d’extensions permettent de récupérer le résultat directement sans avoir à manipuler la classe “HttpOperationResponse”. Nous aurons 2 méthodes d’extensions pour chacune des fonctions de la classes “Values” : une synchrone et une asynchrone.

Pour ce qui est du code de notre proxy, il est associé à 2 fichiers : “IMyWebServiceClient” et “MyWebServiceClient”. Pour le cas d’exemple, l’interface “IMyWebServiceClient” définit deux contrats : une propriété “BaseUri” de type “Uri” et une propriété “Values” de type “IValue”. Etant donné que pour le cas d’exemple je ne dispose que d’un seul contrôleur, d’où la propriété “Values”, alors il est inutile de vous dire que dans d’autres cas le proxy contiendra autant de propriétés de ce genre qu’il y a de contrôleurs. La classe “MyServiceServiceClient” n’est tout simplement qu’une implémentation de l’interface “IMyWebServiceClient”.

Comme tout générateur de code qui se respecte, le code généré ne contient que des interfaces et classes définies avec le mot-clé “partial”. Ce qui permet d’étendre les classes et interfaces sans modifier le code généré. Aussi avec les interfaces nous pourrons facilement mettre en place nos tests unitaires en utilisant des bouchons (mocks) à la place des implémentations.

L’unique contrôleur de mon service n’utilise que des types simples en entrée comme en sortie : “int” et “string”. Dans certains services ASP.NET Web API, nous disposons de classes faisant office de Model ou ViewModel et vu que ces types sont aussi décrits dans les métadonnées Swagger, alors AutoRest saura générer ces types côté client sans problème.

Les exemples de codes ci-dessous montrent les différentes utilisations faites de notre classe Proxy.

Voici un exemple de code pour récupérer la liste des valeurs avec la méthode “Get” :

try
{
	var client = new MyWebServiceClient();
	var values = client.Values.Get();

	Console.WriteLine("Liste des valeurs trouvées :");
	foreach (var value in values)
	{
		Console.WriteLine("\t" + value);
	}
}
catch (HttpOperationException ex)
{
	Console.WriteLine("Une erreur est survenue : ");
	Console.WriteLine("\t Url path : {0}", ex.Request.RequestUri.AbsolutePath);
	Console.WriteLine("\t Method : {0}", ex.Request.Method);
	Console.WriteLine("\t Code d'erreur : {0}", ex.Response.StatusCode);
}

Exemple de code pour récupérer une valeur via son id avec la méthode “GetById” :

try
{
	var client = new MyWebServiceClient();
	var value = client.Values.GetById(1);

	Console.WriteLine("Valeur d'id  1 : {0}", value);
}
catch (HttpOperationException ex)
{
	Console.WriteLine("Une erreur est survenue : ");
	Console.WriteLine("\t Url path : {0}", ex.Request.RequestUri.AbsolutePath);
	Console.WriteLine("\t Method : {0}", ex.Request.Method);
	Console.WriteLine("\t Code d'erreur : {0}", ex.Response.StatusCode);
}

Exemple de code pour créer une nouvelle valeur avec la méthode “Post” :

try
{
	var client = new MyWebServiceClient();
	client.Values.Post("Nouvelle valeur");

	Console.WriteLine("La valeur a été ajoutée avec succès.");
}
catch (HttpOperationException ex)
{
	Console.WriteLine("Une erreur est survenue : ");
	Console.WriteLine("\t Url path : {0}", ex.Request.RequestUri.AbsolutePath);
	Console.WriteLine("\t Method : {0}", ex.Request.Method);
	Console.WriteLine("\t Code d'erreur : {0}", ex.Response.StatusCode);
}

Exemple de code pour modifier une valeur existante avec la méthode “Put” :

try
{
	var client = new MyWebServiceClient();
	client.Values.Put(1, "Valeur Modifiée");

	Console.WriteLine("La valeur a été modifiée avec succès.");
}
catch (HttpOperationException ex)
{
	Console.WriteLine("Une erreur est survenue : ");
	Console.WriteLine("\t Url path : {0}", ex.Request.RequestUri.AbsolutePath);
	Console.WriteLine("\t Method : {0}", ex.Request.Method);
	Console.WriteLine("\t Code d'erreur : {0}", ex.Response.StatusCode);
}

Exemple de code pour supprimer une valeur existante avec la méthode “Delete” :

try
{
	var client = new MyWebServiceClient();
	client.Values.Delete(1);

	Console.WriteLine("La valeur a été supprimée avec succès.");
}
catch (HttpOperationException ex)
{
	Console.WriteLine("Une erreur est survenue : ");
	Console.WriteLine("\t Url path : {0}", ex.Request.RequestUri.AbsolutePath);
	Console.WriteLine("\t Method : {0}", ex.Request.Method);
	Console.WriteLine("\t Code d'erreur : {0}", ex.Response.StatusCode);
}

Dans les différents exemples de code ci-dessus j’utilise le constructeur par défaut de la classe “MyWebServiceClient” mais différentes surcharges existent. J’utilise les méthodes synchrones mais rien ne nous empêche de les remplacer par des méthodes asynchrones.

Conclusion

Dans cet article j’ai présenté l’outil AutoRest. Ce dernier nous permet de générer une classe Proxy nous facilitant l’écriture du code côté client permettant de communiquer avec le service web. Ce dernier doit obligatoirement exposer ses métadonnées en respectant les spécifications Swagger sans cela AutoRest ne sera d’aucune utilité étant donné que Swagger est le seul modeleur utilisable avec cet outil. Le code généré avec AutoRest est compatible avec les projets Visual Studio suivants :

  • applications Desktop (.NET 4.0 and .NET 4.5),
  • applications Web (.NET 4.0 and .NET 4.5),
  • applications Windows Phone (8.1),
  • applications Windows Store (8.1),
  • les bibliothèques de classes portables

Ne ratez plus aucunes actualités avec la newsletter mensuelle de SoftFluent