Sélectionner une page

Sommaire

Programmation Orientée Objet, Design/Architectural Patterns, … Vous en avez déjà entendu parler. Mais savez vous précisément ce en quoi ça consiste ?

Ces 8 articles vous permettront de comprendre les grands principes qui se cachent derrière ces termes techniques, mais également d’apprendre comment et pourquoi les utiliser.

Introduction

Dans le cours sur l’Architecture Orientée Service, nous avons vu rapidement ce qu’était un Web Service, le protocole HTTP sur lequel il est généralement basé, et les problématiques qu’une telle architecture permet de résoudre. Dans ce cours, nous verrons comment implémenter un Web Service, ainsi que les trois modèles de Web Service les plus utilisés.

Le protocole HTTP

Lorsqu’on travail avec HTTP, il est important de comprendre les parties essentielles de ce protocole. En effet, HTTP ne sert pas uniquement à transmettre des informations au niveau de la couche réseau, mais permet aux développeurs de l’intégrer entièrement, voir de baser leurs applications dessus. De plus, il est obligatoire de connaître ce protocole afin d’implémenter le modèle REST (qu’on verra plus bas).

La méthode/Le verbe

Il en existe plusieurs, les plus importants/utilisés correspondent aux action CRUD (Create, Read, Update, Delete). Cette méthode permet de définir le type d’action que l’on souhaite effectuer :

  • POST : Ajouter une ressource (Create)
  • GET : Récupérer une ressource (Read)
  • PUT : Modifier une ressource (Update)
  • DELETE : Supprimer une ressource (Delete)

Un ressource peut être un utilisateur, un groupe, un numéro de téléphone, un commentaire, etc… Cela dépend entièrement de l’application.

La méthode n’est présente que dans les Requêtes, et non les Réponses.

L’en-tête

Une requête/réponse HTTP est composée d’un en-tête. Ce bloc permet d’apporter des informations supplémentaires, telles que le format des données, la langue, l’encodage, etc…

Le corps

Dans ce bloc sont regroupées toutes les informations nécessaires pour effectuer l’action demandée. Ces informations sont propres à l’application. Si le but de la requête est d’ajouter un utilisateur, on renseignera dans ce bloc le prénom, le nom, etc… S’il s’agit d’une réponse d’un serveur Web par exemple, on trouvera dans ce bloc le code HTML/JSON/etc…

Paramètres

Le corps permet de définir un grand nombre de paramètres, néanmoins, parfois on préférera intégrer des paramètres directement dans l’URL. Ces paramètres forment ce qu’on appel la “Query String”. Pour ajouter des paramètres, il suffit d’ajouter à l’URI un “?”, suivi des paramètres sous le format “key=value”, chaque paramètre étant séparé par un “&”. Exemples :

  • http://example.com/users?age=18&sort=ASC
  • http://example.com/comment?id=42

Le code HTTP

Les réponses définissent une information supplémentaire. Il s’agit du code HTTP. Ce code permet de définir le type de réponse parmi une liste existante. Il en existe plein, et chacun permet d’apporter des informations supplémentaires par rapport au traitement de la requête. Exemples :

  • 200 : Succès de la requête
  • 301/302 : Redirection
  • 403 : Accès refusé
  • 404 : Ressource introuvable
  • 500 : Erreur serveur

Exemples de Requêtes/Réponses

Exemple d’une requête :

    GET /user/42 HTTP/1.0
    Host: example.com
    Referer: http://example.com

Exemple d’une réponse :

    HTTP/1.0 200 OK
    Content-Type: text/html
    Content-Length: 19

    <p>Hello World!</p>

REST

Le modèle REST est entièrement basé sur le protocole HTTP, et définit une manière bien précise de l’utiliser. Une application est dite RESTful lorsqu’elle respecte les règles définies par le modèle REST.

L’URI

L’identifiant de la ressource doit être intégralement dans l’URI (avant le « ? »). C’est à dire que les paramètres tels qu’un tri ou un filtre, doivent figurer dans la “Query String” (après le « ? »), et non directement dans l’URI. Exemple :

  • http://example.com/users/42 // Utilisateur n°42
  • http://example.com/posts/1/comments/23 // Commentaire n°23 du Poste n°1
  • http://example.com/users?age=18sort=ASC // Utilisateurs de 18 ans par ordre croissant

Les verbes HTTP

Le verbe HTTP permet d’ajouter une valeur sémantique à la requête. C’est-à-dire qu’en plus d’indiquer la ressource ciblée par la requête (l’URI), on va pouvoir définir un type d’action (récupérer, ajouter, modifier, supprimer, etc…). Exemples :

  • Récupérer l’utilisateur ayant l’id 42 : GET /users/42
  • Récupérer tous les utilisateurs : GET /users
  • Supprimer l’utilisateur ayant l’id 42 : DELETE /users/42
  • Modifier l’utilisateur ayant l’id 42 :  PUT /users/42
  • Ajouter un utilisateur : POST /users

Certaines de ces requêtes ont la même URI, car elles pointent sur la même ressource. Et pourtant le traitement qui sera effectué par l’application sera différent en fonction du verbe utilisé. Si on effectue un POST sur “/users”, on ajoutera un utilisateur, alors que si on effectue un GET sur cette même URI, on listera tous les utilisateurs.

Le format de la ressource

Les informations demandées lors d’un GET par exemple, sont une représentation d’une ressource. Le client peut alors préciser le format dans lequel il souhaite récupérer ces informations. Ce format est précisé dans l’en-tête de la requête HTTP avec le paramètre “Accept”. Exemple :

Requête

GET /users/42
Host: example.com
Accept: application/json
Réponse

HTTP/1.0 200 OK
Content-Type: application/json

{
“first-name”: “Jon”,
“last-name”: “Snow”,

}

Les formats les plus utilisés par les Web Services sont JSON et XML, mais rien ne vous empêche de proposer d’autres formats tels que YAML, ou bien HTML.

Vous pouvez aussi proposer plusieurs formats, et retourner un résultat formaté dans le langage demandé par le client via le paramètre “Accept”.

Avantages

  • Simple à implémenter
  • Simple à utiliser
  • Il suffit de connaître les ressources pour pouvoir l’utiliser
  • Adapté à une utilisation orientée “ressources” ou “données”

Inconvénients

  • Pas prévu pour exécuter des actions autres que CRUD
  • Ne permet pas de générer automatiquement le code nécessaire au client pour l’utiliser
  • Dépendant du protocole HTTP

SOAP

SOAP est, au même titre que REST, un modèle de Web Service. Celui-ci repose sur le format XML, et est généralement utilisé avec le protocole HTTP, mais peut tout à fait en utiliser un autre.

Structure des informations

Toutes les informations transmises se trouvent dans une “enveloppe”, celle-ci est composée de plusieurs parties :

  • L’en-tête : optionnel, apporte des informations supplémentaires pour le traitement
  • Le corps : contenu de la requête/réponse

Les Endpoints

Le but d’un Web Service est d’exposer des méthodes sur Internet/Intranet. Ces méthodes sont accessibles via des endpoints. Il s’agit d’adresses permettant d’exécuter l’action correspondante.

Prenons l’exemple d’un Service d’envoi de SMS. Un endpoint pourrait être “http://sms.server.fr/send”.

Contrairement à REST, SOAP n’utilise pas les verbes HTTP comme valeur sémantique dans le traitement des requêtes. Exemple : pour la suppression d’un utilisateur en REST, on exécuterait une requête du type “DELETE http://example.com/users/1”, alors qu’en SOAP, on utiliserait plutôt l’adresse “http://example.com/deleteUser”. 

WSDL

Le WSDL (prononcé Whiz-Deul) est un langage de description basé sur XML. Son but est de fournir une description complète des Web Services, de manière indépendante des technologies utilisées (langage, serveur, etc…).

Concrètement, lorsque vous créez un Web Service en SOAP, certains outils vous permettent de générer automatiquement le fichier WSDL correspondant. Le résultat est un fichier XML, assez verbeux, détaillant chaque action proposée par votre Web Service, les types de données etc… Bref, tout ce qui est nécessaire pour pouvoir développer un client capable de communiquer avec votre Web Service.

Bien sûr, vous pouvez créer ce fichier vous même. Exemple :

Exemple de WSDL

Comme vous pouvez le voir, un fichier WSDL est peu agréable à regarder, car il ne s’agit pas d’une documentation utilisateur. En effet, le réel intérêt de ce fichier est le fait de pouvoir générer (automatiquement grâce à votre IDE, ou manuellement), des classes permettant d’utiliser le Web Service.

Grâce à ces classes jouant le rôle de “Proxy”, votre application cliente pourra utiliser le Web Service facilement, comme s’il était directement intégré dans votre programme.

Avantages

  • Documentation naturelle de part la présence du WSDL
  • Génération des classes côté client possible
  • Adapté à une utilisation orientée “fonctions”
  • Compatible avec d’autres protocoles que HTTP

Inconvénients

  • Difficile et lourd à implémenter
  • WSDL lourd et long à réaliser « from scratch »

GraphQL

GraphQL est, au même titre que REST et SOAP, un modèle de Web Service, créé par Facebook en 2012.

Sa force réside dans le fait qu’il permet au client de décrire avec précision les données dont il a besoin (ex: récupérer uniquement le prénom et le nom d’un utilisateur, au lieu de récupérer l’objet complet), allégeant ainsi les réponses du serveur. De plus, il est possible d’obtenir plusieurs ressources, ou d’effectuer plusieurs traitements, en une seule requête HTTP.

Un exemple vaut mieux qu’un long discours, alors voici ce à quoi peut ressembler une requête GraphQL :

getUser (id: 123) {
    id
    firstname
    lastname
    groups {
        id
        name
        admin {
            id
            email
        }
    }
    phoneNumbers {
        countryCode
        number
    }
}

Une réponse à cette requête pourrait ressembler à ceci :

{
    "id": 123,
    "firstname": "Jean",
    "lastname": "Michel",
    "groups": [
        {
            "id": 1,
            "name": "Informatique",
            "admin": {
                "id": 1,
                "email": "informatique@example.com"
            }
        },
        {
            "id": 7,
            "name": "Comptabilité",
            "admin": {
                "id": 8,
                "email": "comptabilite@example.com"
            }
        }
    ],
    "phoneNumbers": [
        {
            "countryCode": "33",
            "number": 123456789
        },
        {
            "countryCode": "33",
            "number": 987654321
        }
    ]
}

Comme vous pouvez le constater, dans l’exemple ci-dessous, nous avons demandé à ne récupérer que l’id, le prénom, et le nom de l’utilisateur, ainsi que les groupes auxquels il appartient, et ses numéros de téléphone, pour l’utilisateur ayant l’id numéro 123.

Pour chaque groupe auquel il appartient, on récupère également l’id du groupe, le nom du groupe, ainsi que l’id et l’e-mail de l’utilisateur qui est administrateur du groupe.

Pour chaque numéro de téléphone de l’utilisateur, on récupère le code du pays, ainsi que le numéro de téléphone.

C’est en cela que GraphQL est très intéressant. La requête (surtout lorsqu’il s’agit d’une liste d’éléments), s’en retrouve beaucoup plus légère, et on peut en une seule requête, récupérer des informations stockées dans des relations (ex: groupes, numéros de téléphone) de la ressource principale (l’utilisateur dans le cas présent).

Dans cet exemple, nous exécutons la requête « getUser », mais il est possible d’ajouter en dessous d’autres requêtes GraphQL, d’envoyer le tout en une seule requête HTTP, et de récupérer la totalité des informations ensuite.

Queries

Une « Query » en GraphQL correspond à une requête consistant à « lire » des données (et donc n’effectuer aucune action).

La requête précédente est un bon exemple. Celle-ci prend un paramètre (l’id de l’utilisateur), et retourne les informations associées, en se limitant à la description de la requête (seulement l’id, le prénom, le nom, les groupes, et les numéros de téléphone).

Mutations

Une « Mutation » en GraphQL correspond à une requête consistant à effectuer un traitement (modifier une ressource en base, envoyer un e-mail, etc…).

Tout comme les Queries, les mutations peuvent prendre des valeurs en argument, et retourner une autre valeur (elle-même pouvant être un objet, lequel pourrait être décrit dans le corps de la mutation, afin de limiter les données retournées).

Schéma

Pour fonctionner, GraphQL s’appuie sur un schéma défini côté serveur. Ce schéma a pour but de définir les différents objets qui composent l’API, les attributs de chacun de ces objets, ainsi que les queries/mutations qui sont exécutables.

Ce schéma est très intéressant, car il permet à de nombreux outil de faire de l’auto-complétion, voir même de composer une requête en cliquant sur les attributs qui nous intéressent.

Avantages

  • Permet d’optimiser les requêtes HTTP
  • Permet aux clients de disposer d’un panel complet de requêtes, pouvant être « personnalisées » côté client

Inconvénients

  • Demande un minimum de configuration
  • Plus complexe à prendre en main que REST

Conclusion

Les Web Services offrent très concrètement un « service », généralement consommable à travers le protocole HTTP. Mais HTTP n’est pas suffisant pour offrir un service cohérent de bout en bout. Viennent ainsi s’ajouter les différents types de Web Services tels que SOAP, REST, et GraphQL (pour ne citer que les plus utilisés).

Ces modèles permettent de définir une cohérence à travers toute l’API :

  • Aujourd’hui, REST est très utilisé, car il s’agit probablement du modèle le plus simple à mettre en place
  • GraphQL lui, gagne du terrain avec les années, mais nécessite un minimum de formation pour le mettre en place.
  • SOAP commence à se faire rare, de part son aspect chronophage, et peu séduisant.

Aucun de ces modèles n’est « magique ». Chacun nécessite d’être mis en place côté backend, avec un minimum de configuration. Il existe plein de packages, pour chaque langages, permettant de faciliter la mise en place de l’API, mais aucun ne fait tout le travail à la place du développeur. Même avec GraphQL, chaque requête devra être codée « manuellement », afin d’aller récupérer en base la ressource demandée, ou bien pour déclencher le traitement souhaité.

Pour résumer

Web Service : Service exposé sur le réseau Internet/Intranet

HTTP : Protocole simple, principalement utilisé par les Web Services et applications Web en général

REST : Modèle de Web Service orienté “ressource”

SOAP : Modèle de Web Service orienté “fonction”

GraphQL : Modèle de Web Service « ressource » et « fonction »