Projet webservices pour l'Efrei
Find a file
2023-01-13 13:19:35 +01:00
img changes images to better quality 2023-01-13 13:19:35 +01:00
migrations Remove TODO constraint for editor from table title, we're not dealing with that 2023-01-10 21:32:38 +01:00
soap Replace hello filenames to ping 2023-01-12 13:34:46 +01:00
src Fix artemis 2023-01-13 13:01:55 +01:00
.env Create database with a simple table cache 2022-12-09 14:57:01 +01:00
.gitignore Remove useless newline 2023-01-05 22:27:58 +01:00
Cargo.lock Decode incoming request url 2023-01-05 17:17:38 +01:00
Cargo.toml Decode incoming request url 2023-01-05 17:17:38 +01:00
diesel.toml Create database with a simple table cache 2022-12-09 14:57:01 +01:00
Makefile Remove old latex docs 2023-01-12 17:44:10 +01:00
README.md Minor changes for documentation 2023-01-13 11:44:31 +01:00
requirements.txt Minor changes, add requirements.txt 2023-01-13 08:39:56 +01:00

Projet webservices - Réalisation de services web

Objectifs

Illustration sur un cas concret des problématiques liées à l'utilisation de SOAP et REST.

Composants

Un serveur fournit des services par le biais de deux API (REST et SOAP), qui sont requêtées par deux clients.

Pour certaines fonctionnalités, le serveur doit faire des requêtes auprès d'une API publique. Il doit donc embarquer une fonctionnalité de client auprès de l'API publique.

Le projet se base sur l'API publique de Mirabel. Cette API, sous licence ouverte, fournit un accès facilité aux revues scientifiques.

Languages

  • Le serveur, hephaistos, est écrit en Rust. Son composant "client", qui requête l'API publique de Mirabel, est également écrit en Rust.
  • Un client CLI, artemis, écrit en Python.
  • Un client GUI, kratos, écrit en PHP.

Getting started

Les clients font des requêtes sur le nom de domaine hephaistos donc il faut permettre la résolution de noms pour ce domaine. Si le client et le serveur sont lancés sur la même machine, on peut par exemple sur UNIX faire :

echo "127.0.0.1  hephaistos" >> /etc/hosts

Les trois composants du projet sont dans le même dépôt :

  • Artemis (client Python) :

    Les fonctionnalités utilisées obligent d'utiliser Python 3.10 au minimum. Les librairies requests et zeep sont nécessaires et sont listées dans le fichier requirements.txt.

    On peut les installer avec :

    pip3 install -r requirements.txt
    

    ou par exemple sur Debian via apt :

    apt install python3-requests python3-zeep
    

    et sur Archlinux :

    pacman -S python-requests python-zeep
    
  • Kratos (client PHP) :

    Afin de proposer un client GUI, le client PHP est fait pour être lancé localement et consulté via navigateur. Il faut installer PHP, sur Debian :

    apt install php
    

    sur Archlinux :

    pacman -S php
    

    Pour lancer le client :

    php -S localhost:8000 src/kratos.php
    

    Et ouvrir http://localhost:8000 dans un navigateur.

  • Hephaistos (serveur Rust) :

    Il faut installer rustup pour disposer des outils d'installation, de compilation et de gestion de dépendance.

    Par exemple sur Debian :

    apt install rustup
    

    sur Archlinux :

    pacman -S rustup
    

    Puis, pour lancer le serveur (et le compiler en mode production si nécessaire) :

    cargo run --release
    

    On peut également générer une documentation du code Rust et l'ouvrir dans un navigateur :

    cargo doc --document-private-items --no-deps --open
    

Fonctionnalités

Architecture des services (partie REST)

rest-architecture

L'API REST est requêtable par trois méthodes HTTP :

  1. GET
    • /api/titre/<titre> : permet une recherche par mot clé (<titre>) pour rechercher la base des titres proposées par Mirabel.
    • /api/historique : liste tout l'historique enregistré : il s'agit des anciennes requêtes que le serveur à reçues.
    • /api/favoris : liste les titres précédemment mis en favoris.
  2. POST
    • /api/favoris/<id> : ajoute un favoris en passant un identifiant (<id>) correspondant à un titre.
  3. DELETE
    • /api/favoris/<id> : retire un favoris précédemment ajouté, en passant un <id>.

Architecture des services (partie SOAP)

soap-architecture

Le service fourni par le protocole SOAP correspond simplement à un Ping/Pong. Le même endpoint est utilisé : /api/ping pour les deux étapes nécessaires à une requête SOAP sur HTTP :

  • Un GET /api/ping renvoie le fichier WSDL décrivant les services SOAP disponibles. Ce service est un pingRequest.
  • Pour faire la requête SOAP correspondante, le client doit faire une requête POST sur /api/ping avec les données XML pour la requête pingRequest. Il recevra alors un pongResponse.

Architecture technique

Serveur - Hephaïstos (Rust)

Le code du serveur est organisé de manière extrêmement modulaire. Le fichier src/main.rs est le point d'entrée du binaire. Il fait un appel à la fonction run() du fichier src/lib.rs en récupérant les erreurs remontées.

Le langage Rust incite fortement à une gestion fine des erreurs, et il est donc primordial de définir quelles erreurs doivent arrêter le programme (lors du démarrage du serveur par exemple) et quelles erreurs doivent être gérées plus finement. Il est par exemple inconcevable de planter le serveur lors de la réception d'une requête erronée.

La fonction run() est donc l'endroit ou toute la logique est définie.

Le serveur commence par écouter sur le socket défini (par défaut 0.0.0.0:8080). C'est la première chose qui est faite pour que le programme puisse quitter tôt, au moindre problème (lors du bind notamment). Ce listen() est fait sur un objet Ear, qui regroupe les éléments utiles pour la partie écoute du serveur.

Ensuite, le serveur met à jour sa base locale : il la remplit lorsqu'elle est vide et met à jour les éléments déjà présents.

La base locale est une base de données PostgreSQL. Lors de cette mise à jour, c'est la table title qui est remplie : elle contient les titres des revues sur Mirabel, qui sont récupérés par un appel GET vers son API REST publique (https://reseau-mirabel.info/api/titres).

La base contient également les tables favorite et history.

Pour interagir avec PostgreSQL, le serveur utilise la bibliothèque Diesel, dans le module database. Ce module contient le code haut niveau appelé par les fonctions de chaque ressource, ainsi que deux sous-modules pour la gestion des tâches plus bas niveau :

  • crud.rs :
    • établir la connexion avec la base de données
    • créer des éléments
    • lire des éléments
    • modifier des éléments
    • supprimer des éléments
  • errors.rs : définit les erreurs en rapport avec la base de données, pour que les fonctions puissent remonter les erreurs à la fonction appelante.

Ensuite, le serveur peut commencer à gérer les requêtes entrantes.

Pour chaque requête, il extrait la première ligne (correspondant à la méthode HTTP, la ressource, et la version HTTP). Cette ligne est parsée puis un routage s'occupe d'appeler la fonction correspondante à la ressource demandée.

La gestion d'une requête commence toujours par enregistrer un nouvel élément dans l'historique. Si cet appel échoue, la requête dans son ensemble est ignorée.

Pour l'envoi des données au client, un objet Mouth est créé. Les méthodes de cet objet prennent en compte les erreurs remontées pour adapter le code HTTP (200, 400, 404, 500...) et la donnée pour la ressource, notamment le message d'erreur.

Client - Artemis (Python)

Les requêtes sont faites grâce aux librairies requests et zeep (pour la partie SOAP).

Le fichier XML reçu par la réponse SOAP est parsé par zeep et le retour est affiché sur le terminal.

Pour les requêtes REST, les réponses reçues en JSON sont parsées localement. Les réponses peuvent essentiellement être des éléments historique ou titre. Deux classes ont donc été créées pour représenter ces éléments, History et Title.

Artemis est un client CLI, il fait donc l'interface entre arguments reçus en ligne de commande et requêtes HTTP nécessaires.

Plus précisément, les arguments possibles sont :

$ ./src/artemis.py
usage: artemis.py [-h] [-t <titre>] [-f <article number>] [-d <article number>] [-l] [-H] [-p]

options:
  -h, --help            show this help message and exit
  -t <titre>, --titre <titre>
                        use this argument to query the article you want
  -f <article number>, --favoris <article number>
                        use this argument to add/register an article into your favorite list
  -d <article number>, --delete <article number>
                        use this argument to remove an article from your favorite list
  -l, --liste           use this argument to list all your registered favourites
  -H, --historique      use this argument to list all your previous requests
  -p, --ping            say hello to Hephaistos

Une recherche de titre pour "science and technology" aura le résultat suivant :

$ ./src/artemis.py -t "science and technology"

TITRE : African Journal of Environmental Science and Technology
ID MIRABEL : 5547
URL : https://academicjournals.org/ajest/

TITRE : African journal of science and technology=Journal africain de science et technologie
ID MIRABEL : 5632
URL : None

TITRE : An International Journal of Science and Technology
ID MIRABEL : 5635
URL : http://afrrevjo.net/?q=stech_home/archive

La requête API correspondante est GET /api/titre/science%20and%20technology HTTP/1.1.

Client - Kratos (PHP)

Le client PHP consiste en un fichier src/kratos.php. Il peut se lancer avec php -S localhost:8000 src/kratos.php.

Les fonctionnalités implémentées sont les suivantes :

  • Un bouton Ping permet d'envoyer la requête SOAP pour /api/ping.
  • Un formulaire de recherche permet de faire une requête pour /api/titre/<recherche>. Lors du retour par le serveur, la page fait une aussi une requête pour /api/favoris. Chaque titre retourné par le serveur peut ainsi être comparé à la liste des favoris pour pré-cocher les checkbox du formulaire de favoris.
  • Ce formulaire de favoris permet de faire une requête POST /api/favoris/<id> pour chaque titre coché, et ainsi ajouter le titre aux favoris.
  • Un bouton Historique permet d'afficher la liste des requêtes précédentes, grâce à un appel GET /api/historique.
  • Un bouton Favoris permet d'afficher les favoris enregistrés.