Client Rest

Et voilà, c’est fait ! J’ai fait un petit client Rest tout simplissime en C# 🙂

L’idée est ici d’avoir une petite API qui se charge pour moi de faire l’appel Web et la dé-sérialisation des données dans un objet C#. Je m’appuie sur les contrats WCF pour la définition de l’objet en mémoire (DataContract, DataMember, etc.).

Imaginons que je désire récupérer les informations de mon personnage de Wow avec sa guilde. Blizzard a mis à disposition des serveurs que nous pouvons interroger en JSON. Pour notre cas de figure, la documentation de Blizzard indique ceci :

URL = Host + "/api/wow/character/" + Realm + "/" + CharacterName
       + "?locale=" + locale + "&fields=" + optional(s) field(s)

Realm = <proper realm name> | <normalized realm name>

Ce qui nous donnera un appel Web qui ressemblera à ceci :

GET /api/wow/character/La Croisade écarlate/Shoubido?fields=guild
Host: eu.battle.net

La documentation indique également la structure des données en sortie :

HTTP/1.1 200 OK
<http headers>

{
   "realm": "Medivh",
   "name": "Uther",
   "level": 85,
   "lastModified": 1307596000000,
   "thumbnail": "medivh/1/1-avatar.jpg",
   "race": 1,
   "achievementPoints": 9745,
   "gender": 0,
   "class": 2,
   "guild":{
    "name":"Knights of the Silver Hand",
    "realm":"Medivh",
    "level":25,
    "members":50,
    "achievementPoints":7500,
    "emblem":{
      "icon":119,
      "iconColor":"ffb1b8b1",
      "border":0,
      "borderColor":"ffffffff",
      "backgroundColor":"ff006391"
    }
  }
}

Nous allons dans un premier temps nous focaliser sur la classe qui contiendra les données à récupérer. La déclaration est par exemple la suivante :

    [DataContract]
    public class CharacterRawData : IExtensibleDataObject
    {
        [DataMember(Name = "realm", IsRequired = true)]
        public string Realm { get; set; }

        [DataMember(Name = "name", IsRequired = true)]
        public string Name { get; set; }

        [DataMember(Name = "level", IsRequired = true)]
        public long Level { get; set; }

        [DataMember(Name = "lastModified", IsRequired = true)]
        public long LastModified { get; set; }

        // ... Les autres champs ne sont pas présentés

        public ExtensionDataObject ExtensionData { get; set; }
    }

Le point important dans cette déclaration de classe est qu’il faut hériter de l’interface IExtensibleDataObject. Petit rappel WCF : Cette interface impose la présence de la propriété ExtensionData qui sera alimentée par les champs non déclarés dans la classe au moment de la sérialisation / dé-sérialisation des données par le moteur WCF. Ainsi, nous ne pouvons pas perdre les informations restituées par le serveur de Blizzard.

Une fois cet objet défini, il suffit d’utiliser mon petit client Rest comme suit :

// Création du client Rest
var restClient = new RestClient(new Uri("http://eu.battle.net"));

// On demande au client Rest de récupérer les données
var result = restClient.Retrieve<CharacterRawData>(
  RestResource.Create("/api/wow/character/{realm}/{character name}")
  .AddPathParameter("realm", "La Croisade écarlate")
  .AddPathParameter("character name", "Shoubido")
  .AddQueryParameter("fields", "pvp")
  .AddQueryParameter("locale", CultureInfo.CurrentCulture));

En fait, pour résumer :

  1. Nous créons un client Rest avec l’adresse du serveur que nous désirons interroger
  2. Nous appelons la méthode « Retrieve » du client Rest. Le type générique de cette méthode correspond au type de la classe qu’elle doit utiliser pour dé-sérialiser les données du serveur (Le type doit obligatoirement implémenter l’interface « IExtensibleDataObject »). Donc ici, la variable « result » est de type « CharacterRawData ». La méthode « Retrieve » prend en paramètre une ressource Rest (« RestResource »). Cette ressource définie les éléments nécessaires pour interroger le serveur.
  3. Nous utilisons la méthode statique « RestResource.Create » pour créer une nouvelle ressource Rest. Cette ressource définie l’URL à interroger (chemin + paramètres GET éventuels).
  4. Le chemin est paramétrée avec le nom de la guilde et le nom du personnage. Chaque paramètre du chemin est définie entre accolades. Afin de valoriser ces paramètres, il faut utiliser la fonction « AddPathParameter » qui prend en paramètre le nom du paramètre ainsi que sa valeur (qui peut être de tout type – Le client Rest convertira la valeur en chaîne de caractères).
  5. Enfin, l’URL peut posséder des paramètres GET qui sont valorisés en utilisant la fonction « AddQueryParameter » qui prend en paramètre le nom du paramètre GET ainsi que sa valeur (qui peut être de tout type – Le client Rest convertira la valeur en chaîne de caractères).

Et voilà, le tour est joué ! 😀 Le code source de ce petit client Rest se trouve ici.

Enjoy !