I. Introduction▲
Au vu des besoins d'interaction de plus en plus croissants entre une application Web et un ensemble très large de clients (réseaux sociaux, navigateurs, terminaux mobiles, applications natives, etc.), il était indispensable de fournir aux développeurs un moyen de communiquer dans leurs applications avec ces différents types de clients.
Web API a fait son apparition comme une technologie pour WCF (Windows Communication Framework). Elle a pour objectif principal de fournir un cadre pour exposer applications, données et services sur le Web directement à travers HTTP.
Les fonctionnalités et améliorations qui ont été apportées à ASP.NET Web API ont été intégrées en totalité comme partie du Framework Web ASP.NET MVC 4.
Dans ce tutoriel introductif qui est le premier d'une série sur le sujet, nous verrons comment créer une API Web avec ASP.NET MVC et comment consommer celle-ci. L'exemple portera sur une API Web qui va renvoyer une liste de clients. La liste sera ensuite affichée dans une interface via jQuery et également en utilisant HttpClient pour une application native.
II. Prérequis▲
Pour la bonne compréhension de cet article, vous devez disposer des connaissances de base en C#, ASP.NET MVC et JavaScript.
III. Outils▲
L'un des outils suivants peut être utilisé pour les exemples :
- Visual Studio 2012 ;
- Visual Studio 2010 Service pack 1 avec ASP.NET MVC 4 installé ;
- Visual Web Developer 2010 Service Pack 1 avec ASP.NET MVC installé.
IV. Description▲
Le support d'ASP.NET Web API dans le framework ASP.NET MVC permet de créer facilement des services Web RestFull qui peuvent être consommés à partir d'un large éventail de clients (réseaux sociaux, navigateurs, terminaux mobiles, etc.). Web API fournit les fonctionnalités suivantes :
- un modèle de programmation HTTP moderne : l'API Web permet d'accéder directement et manipuler les requêtes et réponses HTTP à l'aide d'un nouveau modèle objet HTTP fortement typé. Le même modèle de programmation HTTP est pratiquement disponible sur le client par l'intermédiaire de HttpClient, pouvant être utilisé pour appeler des API Web dans n'importe quelle application .NET ;
- négociation de contenu : le client et le serveur peuvent travailler ensemble afin de déterminer le bon format pour les données retournées à partir d'une API. Les formats pris en charge par défaut sont XML et JSON. Le développeur pourra élargir ce soutien en ajoutant ses propres formats, ou même en remplaçant la stratégie de négociation de contenu par défaut ;
- prise en charge complète des routes : l'API Web prend désormais en charge l'ensemble des fonctionnalités de route qui ont toujours été une partie de la pile Web, y compris les paramètres d'itinéraire et les contraintes. En outre, la cartographie des actions possède un support complet pour les conventions, de sorte que le développeur n'aura plus besoin d'appliquer des attributs à une classe ou méthode. La configuration de Web API se fait uniquement à travers le code ;
- composition de requêtes : Web API permet de prendre rapidement en charge l'interrogation par l'intermédiaire des conventions URL OData. Lorsque le développeur retourne un type IQueryable de son API Web, le framework fournira un soutien pour OData, rendant facile l'implémentation de la pagination et le tri ;
- validation des modèles : le modèle fournit un moyen facile d'extraire des données de diverses parties d'une requête HTTP et convertit celles-ci en objets .NET, qui peuvent être utilisés par des actions Web API. Web API offre le même support qu'ASP.NET MVC pour la liaison des modèles et la même infrastructure de validation ;
- filtres : l'API Web permet de créer et utiliser facilement des filtres, qui permettent d'encapsuler et d'appliquer divers comportements ;
- améliorations des tests : plutôt que de fixer des détails dans les objets de contexte HTTP statiques, les actions Web API peuvent maintenant travailler avec les instances de HttpResquestMessage et HttpResponseMessage, deux nouveaux objets HTTP qui permettent d'effectuer plus facilement des tests ;
- support de l'IoC : Web API prend en charge le modèle de service de localisation mis en œuvre par ASP.NET MVC, qui permet de résoudre les dépendances pour de nombreux dispositifs différents. Le développeur peut facilement intégrer cela avec un conteneur IoC, ou une bibliothèque permettant l'injection de dépendances ;
- flexibilité lors de l'hébergement : Web API peut être déployée dans n'importe quel type d'application ASP.NET (y compris à la fois ASP.NET MVC et ASP.NET Web Forms). Web API peut également être hébergé au sein de votre plateforme, si vous ne voulez pas utiliser ASP.NET/IIS pour le faire. Cela vous donne un maximum de flexibilité dans la façon dont vous l'utilisez.
V. Création d'une première API Web▲
Lancez votre environnement de développement. Déroulez le menu Fichier et cliquez sur "Nouveau projet". Dans la liste des modèles de projets qui va s'afficher, sélectionnez le modèle "Application Web ASP.NET MVC 4".
Renseignez le nom de l'application ainsi que l'emplacement ou celle-ci sera enregistrée et cliquez par la suite sur OK. Pour notre cas, nous allons donner comme nom à l'application "FirstWebAPI".
La fenêtre des modèles de projet ASP.NET MVC s'affiche. Vous remarquez certainement la présence d'un nouveau modèle de projet Web API. Sélectionnez celui-ci et cliquez sur OK.
Visual studio va procéder à la création du nouveau projet avec un certain nombre de fichiers par défaut. Avant de continuer, nous allons examiner et expliquer les éléments qu'il y a de différents dans ce modèle de projet par rapport aux autres modèles de projets ASP.NET MVC. Ouvrez le fichier ValuesController du dossier Controllers. Vous y trouverez les lignes de code suivantes :
using
System;
using
System.
Collections.
Generic;
using
System.
Linq;
using
System.
Net;
using
System.
Net.
Http;
using
System.
Web.
Http;
namespace
FirstWebAPI.
Controllers
{
public
class
ValuesController :
ApiController
{
// GET api/values
public
IEnumerable<
string
>
Get
(
)
{
return
new
string
[]
{
"value1"
,
"value2"
};
}
// GET api/values/5
public
string
Get
(
int
id)
{
return
"value"
;
}
// POST api/values
public
void
Post
(
string
value
)
{
}
// PUT api/values/5
public
void
Put
(
int
id,
string
value
)
{
}
// DELETE api/values/5
public
void
Delete
(
int
id)
{
}
}
}
Le contrôleur utilisé pour une API Web doit obligatoirement hériter de ApiController. Les actions effectuées sur les données sont couramment la lecture, l'écriture, la suppression et la modification. Par défaut, ces actions sont implémentées dans une API Web via les requêtes Get(), Post(), Put() et Delete().
V-A. Système de routage pour Web API▲
Le système de routage utilisé pour une API Web est légèrement différent de celui d'une application ASP.NET MVC. Pour WebAPI, vous n'avez pas besoin de renseigner la méthode d'action comme c'est le cas avec ASP.NET MVC. L'API Web utilise la méthode HTTP et non le chemin de l'URI pour sélectionner la méthode d'action. Si vous vous êtes familiarisé avec le routage pour ASP.NET MCV, vous n'aurez aucune difficulté en ce qui concerne Web API.
L'utilisation de HTTP permet donc à Web API d'identifier automatiquement la méthode du contrôleur qui sera exécutée en fonction du verbe HTTP qui est effectué (GET, POST, etc.).
Pour prendre en charge cela, un nouveau système de routage est défini au sein de votre application. Si vous ouvrez le fichier RouteConfig.cs du dossier App_start, vous aurez les lignes de code suivantes :
routes.
MapHttpRoute
(
name:
"DefaultApi"
,
routeTemplate:
"api/{controller}/{id}"
,
defaults:
new
{
id =
RouteParameter.
Optional }
);
À la différence de MVC, la route est ajoutée dans MapHttpRoute(). Dans cette configuration, "api" est un segment de chemin littéral. Il est utilisé dans la définition de la route pour éviter des collisions avec le routage d'ASP.NET MVC. {controller} et {id} sont des variables référencées, permettant de définir respectivement le contrôleur et la valeur qui sera utilisée comme identifiant.
Méthode HTTP | Chemin URI | Action | Description |
---|---|---|---|
Get | api/values | Get() | Retourne toutes les données comme un IEnumerable. |
Get | api/values/2 | Get() | Retourne l'élément ayant pour Id 2. |
Post | api/values | Post() | Enregistrement d'un nouvel élément. |
Put | api/values/2 | Put() | Modification de l'élément ayant pour Id 2. |
Delete | api/values/2 | Delete() | Surpression de l'élément ayant pour Id 2. |
V-B. Création du modèle▲
Voyons maintenant concrètement comment nous pouvons utiliser une API Web. Je vais me limiter à un exemple simple qui montre comment exposer et consommer les données d'une API dans une application Web avec JavaScript et dans une application console avec HTTPClient. L'exemple portera sur une base de données de clients.
Vous allez dans un premier temps ajouter une nouvelle classe dans votre dossier modèle en faisant un clic droit sur celui-ci, et en sélectionnant la ligne "Ajouter", puis "Classe" comme l'illustre la capture ci-dessous :
Dans la fenêtre qui va s'afficher, donnez le nom "Customer.cs" à votre fichier et validez par la suite sur OK.
Dans ce fichier, vous allez ajouter les lignes de code suivantes :
public
class
Customer
{
public
int
Id {
get
;
set
;
}
public
string
FirstName {
get
;
set
;
}
public
string
LastName {
get
;
set
;
}
public
string
EMail {
get
;
set
;
}
}
V-C. Création du contrôleur▲
Lorsque c'est fait, vous allez ajouter un nouveau contrôleur à votre application. Pour cela, faites un clic droit sur le dossier "Controllers", sélectionnez la commande Ajouter, ensuite Contrôleur :
Dans la fenêtre qui va s'afficher, renseignez le nom de votre contrôleur "CustomerController", puis déroulez "Modèle" des "Options de vue de structure", puis sélectionnez "Contrôleur d'API vide" et cliquez par la suite sur "Ajouter" :
Le fichier "CustomerController.cs" sera ajouté à votre projet. Ouvrez celui-ci. Vous allez y ajouter des lignes de code permettant d'initialiser un tableau de clients, de retourner la liste complète des clients et enfin les informations sur un client particulier en fonction de son identifiant.
Le code source qui sera utilisé est le suivant :
public
class
CustomerController :
ApiController
{
Customer[]
Customers =
new
Customer[]
{
new
Customer {
Id =
1
,
FirstName =
"Hinault"
,
LastName =
"Romaric"
,
EMail =
"hr@gmail.com"
},
new
Customer {
Id =
2
,
FirstName =
"Thomas"
,
LastName =
"Perrin"
,
EMail =
"thomas@outlook.com"
},
new
Customer {
Id =
3
,
FirstName =
"Allan"
,
LastName =
"Croft"
,
EMail =
"allan.croft@crt.com"
},
new
Customer {
Id =
3
,
FirstName =
"Sahra"
,
LastName =
"Parker"
,
EMail =
"sahra@yahoo.com"
},
};
public
IEnumerable<
Customer>
GetAllCustomers
(
)
{
return
Customers;
}
public
Customer GetCustomerById
(
int
id)
{
var
Customer =
Customers.
FirstOrDefault
((
c) =>
c.
Id ==
id);
if
(
Customer ==
null
)
{
throw
new
HttpResponseException
(
new
HttpResponseMessage
(
HttpStatusCode.
NotFound));
}
return
Customer;
}
}
V-D. Aperçu du résultat▲
Compilez et exécutez votre application. Dans la barre d'adresse de votre navigateur, renseignez l'URL : "xxx/api/Customer" Avec Internet Explorer 9, vous allez obtenir le résultat suivant :
Cliquez sur ouvrir et sélectionnez "Bloc Notes" pour ouvrir le fichier. Vous trouverez les données suivantes au format JSON dans celui-ci.
[{"Id":1,"FirstName":"Hinault","LastName":"Romaric","EMail":"hr@gmail.com"},
{"Id":2,"FirstName":"Thomas","LastName":"Perrin","EMail":"thomas@outlook.com"},
{"Id":3,"FirstName":"Allan","LastName":"Croft","EMail":"allan.croft@crt.com"},
{"Id":3,"FirstName":"Sahra","LastName":"Parker","EMail":"sahra@yahoo.com"}]
Avec le navigateur Chrome, vous obtenez par défaut les données au format XML :
<ArrayOfCustomer
xmlns
:
i
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://schemas.datacontract.org/2004/07/FirstWebAPI.Models"
>
<Customer>
<EMail>
hr@gmail.com</EMail>
<FirstName>
Hinault</FirstName>
<Id>
1</Id>
<LastName>
Romaric</LastName>
</Customer>
<Customer>
<EMail>
thomas@outlook.com</EMail>
<FirstName>
Thomas</FirstName>
<Id>
2</Id>
<LastName>
Perrin</LastName>
</Customer>
<Customer>
<EMail>
allan.croft@crt.com</EMail>
<FirstName>
Allan</FirstName>
<Id>
3</Id>
<LastName>
Croft</LastName>
</Customer>
<Customer>
<EMail>
sahra@yahoo.com</EMail>
<FirstName>
Sahra</FirstName>
<Id>
3</Id>
<LastName>
Parker</LastName>
</Customer>
</ArrayOfCustomer>
Comme je l'ai signalé plus haut avec la négociation de contenu, Web API peut automatiquement sérialiser votre modèle aux différents formats qui sont supportés (JSON, XML, etc.) et ensuite écrire les données sérialisées dans le corps du message de la réponse HTTP. Le client peut désérialiser l'objet transmis via HTTP tant qu'il peut lire le format de sérialisation. La plupart des clients supportent par défaut le format XML et JSON. Le format par lequel les données peuvent être retournées par l'API Web doit être défini côté client.
VI. Accès aux données avec JavaScript▲
Voyons maintenant comment nous pouvons accéder et afficher ces données dans une page Web HTML en utilisant jQuery.
Pour obtenir une liste de clients, vous devez effectuer une requête HTTP GET sur " /api/customer/ ". Vous pouvez le faire comme suit :
<
script type=
"text/javascript"
>
$(
document).
ready
(
function (
) {
// Envoi de la requête Ajax
$.
getJSON
(
"api/Customer/"
,
function (
data) {
// En cas de succès, 'data' contient la liste des clients.
$.
each
(
data,
function (
key,
val) {
var
str =
val.
Id +
' '
+
val.
FirstName +
' '
+
val.
LastName;
$(
'<li/>'
,
{
html:
str }
).
appendTo
(
$(
'#customers'
));
}
);
}
);
}
);
</
script>
La fonction getJSON est utilisée pour envoyer une requête AJAX vers l'API Web. Un tableau d'objets JSON sera retourné en cas de succès.
Éditez le fichier index.chtml de votre application et remplacez le code dans celui-ci par le code complet ci-dessous :
<header>
<div class
=
"content-wrapper"
>
<div class
=
"float-left"
>
<p class
=
"site-title"
>
<a href
=
"~/"
>
ASP.NET Web API</a></p>
</div>
</div>
<script src
=
"../../Scripts/jquery-1.6.2.min.js"
type
=
"text/javascript"
></script>
<script type
=
"text/javascript"
>
$(
document
).ready
(
function (
) {
// Envoi de la requête Ajax
$.getJSON
(
"api/Customer/"
,
function (
data) {
// En cas de succès, 'data' contient la liste des clients.
$.each
(
data,
function (
key,
val) {
var str =
val.
Id +
' '
+
val.
FirstName +
' '
+
val.
LastName;
$(
'<li/>'
,
{
html
:
str }
).appendTo
(
$(
'#customers'
));
}
);
}
);
}
);
</script>
</header>
<div id
=
"body"
>
<h1>Customers</h1>
<ul id
=
'customers'
/>
</div>
Lorsque vous allez exécuter cette page, vous allez obtenir le résultat suivant :
VII. Lecture d'une API avec HTTPClient▲
Dans une application Web, vous pouvez simplement interagir avec une API Web côté client en appelant les requêtes HTTP Get, Put, Post et Delete dans un script JavaScript ou en utilisant jQuery. Mais, si vous voulez accéder à votre API à partir d'une application Desktop par exemple, comment procéder ?
C'est à ce niveau qu'intervient HTTPClient. HTTPClient est un client moderne HTTP pour les applications .NET. Il peut être utilisé pour consommer avec souplesse et simplicité les fonctionnalités exposées via HTTP. Vous pouvez utiliser HTTPClient pour mettre en œuvre des interactions avec une API Web en envoyant et en recevant des réponses à partir des verbes standards Get, Put, Post et Delete de HTTP grâce aux méthodes GetAsync, PutAsync, PostAsync, DeleteAsync.
L'exemple ci-dessous illustre comment vous pouvez consommer les données au format XML d'une API Web en utilisant la méthode GetAsync.
HttpClient client =
new
HttpClient
(
);
client.
DefaultRequestHeaders.
Accept.
Add
(
new
MediaTypeWithQualityHeaderValue
(
"application/xml"
));
var
response =
client.
GetAsync
(
"http://localhost:59130/api/Customer"
).
Result;
Si vous souhaitez que les données soient retournées au format XML, vous pouvez procéder comme suit :
HttpClient client =
new
HttpClient
(
);
client.
DefaultRequestHeaders.
Accept.
Add
(
new
MediaTypeWithQualityHeaderValue
(
"application/json"
));
var
response =
client.
GetAsync
(
"http://localhost:59130/api/Customer"
).
Result;
La procédure client.DefaultRequestHeaders.Accept.Add() permet de définir le format qui sera utilisé pour sérialiser les données.
La procédure asynchrone GetAsync() de la classe HttpClient() prend en paramètre une URI ou une chaîne de caractères qui représente l'URL de l'API Web. GetAsync effectue une requête HTTP GET en utilisant l'URL passée en paramètre, puis retourne directement une tâche dont la propriété Result (Task.Result) contient la réponse HTTP (HttpResponseMessage).
Il est recommandé lors de l'utilisation d'une méthode asynchrone d'utiliser également le mot clé await pour éviter que l'application ne soit bloquée jusqu'à ce que l'opération soit complète. On peut s'en passer pour une application console, mais pour une solution Desktop, faudra penser à utiliser await pour éviter le blocage de l'interface utilisateur. Pour plus de détails sur async et await, je vous invite à lire cet excellent article sur le sujet : les nouveautés de C# 5.0.
À titre d'exemple, vous allez créer une application console qui consomme l'API que vous avez créée ci-dessus.
Pour cela, vous allez ajouter à votre solution un nouveau projet. Cliquez sur le menu "FICHIER", sélectionnez "Ajouter" puis "Nouveau projet". Sélectionnez le projet "Application Console" et donnez-lui le nom "TestFirstWebAPI".
Après la création du projet, vous allez ajouter une référence à HTTPClient. HTTPClient n'étant pas disponible par défaut dans le Framework .NET ou avec ASP.NET MVC 4, vous devez passer par le gestionnaire de packages NuGet pour ajouter cette dépendance à votre application.
Faites un clic droit sur votre projet dans l'explorateur de solution et sélectionnez la commande "Gérer les packages NuGet…". Lorsque l'interface de NuGet va s'afficher, recherchez le package HTTPClient et cliquez sur "Installer".
L'installation du package va entraîner l'installation des dépendances System.Net.Http et System.Json que vous allez utiliser dans votre application.
Ajoutez une classe dans votre projet ayant la même définition que la classe Customer dans le projet ASP.NET MVC.
On aurait pu (ce qui est conseillé d'ailleurs) créer un projet transversal pour le modèle objets, qui allait être utilisé à la fois par l'API Web et l'application console. Mais, je préfère ne pas le faire afin que l'on se focalise uniquement sur le sujet qui nous intéresse sans être déconcentré par autre chose.
Ajoutez par la suite une référence à System.Net.Http.Formatting et System.Net.Http.Headers.
using
System.
Net.
Http.
Formatting;
using
System.
Net.
Http.
Headers;
Vous allez maintenant ajouter les lignes de code suivantes à la fonction Main de votre application.
HttpClient client =
new
HttpClient
(
);
client.
DefaultRequestHeaders.
Accept.
Add
(
new
MediaTypeWithQualityHeaderValue
(
"application/json"
));
var
response =
client.
GetAsync
(
"http://localhost:59130/api/customer"
).
Result;
if
(
response.
IsSuccessStatusCode)
{
var
Customers =
response.
Content.
ReadAsAsync<
IEnumerable<
Customer>>(
).
Result;
foreach
(
var
c in
Customers)
{
Console.
WriteLine
(
"{0}
\t
{1}
\t
{2}"
,
c.
FirstName,
c.
LastName,
c.
EMail);
}
}
else
{
Console.
WriteLine
(
"{0} ({1})"
,
(
int
)response.
StatusCode,
response.
ReasonPhrase);
}
Console.
ReadLine
(
);
La procédure ReadAsAsync() lit et déserialise automatiquement le corps de la réponse HTTP qui contient la liste des clients.
En appuyant sur F5 pour lancer le débogage de votre application, vous allez obtenir le résultat suivant.
Assurez-vous d'utilisez un numéro de port spécifique pour votre application (59130 pour mon cas). Vous pouvez vérifier cela dans les propriétés du projet, onglet Web :
Vous avez le choix entre utiliser un numéro de port spécifique ou utiliser le serveur Web IIS local si vous en avez. Dans ces cas, le numéro de port ne varie que si vous décidez de le modifier.
VIII. Conclusion▲
ASP.NET WebAPI est un Framework puissant pour le développement des services Web RestFull qui peuvent être consommés par n'importe quel client, indépendamment de la plateforme, tant qu'il supporte les formats de données pris en charge par l'API. Ce tutoriel introductif avait pour objectif de vous donner un premier aperçu de WebAPI et vous familiariser avec celui-ci. Dans un prochain article, nous allons aborder des scénarios un peu plus avancés comme la création d'un service CRUD avec WebAPI et EntityFramework.
IX. Télécharger le code de l'exemple▲
Télécharger le code source sur GitHub
X. Remerciements▲
Je tiens à remercier f-leb pour sa relecture et correction orthographique.