2.1 - Service Web


Service Web

Chapitre 2

RPC - Remote Procedure Call

Depuis très longtemps, la connectivité réseau est utilisé pour permettre à un programme d'exécuter une tâche sur une autre machine.

  • Plusieurs standards/protocoles sont utilisés
  • Demandent souvent de contrôler les 2 côtés de la communication
  • Imposent des technologies

HTTP

API HTTP

En exposant l'interface logicielle, API, via le protocole HTTP, toutes sortes de clients peuvent en bénéficier.

  • Standard établi
  • Interopérabilité
  • Flexible

Paradigmes

Au fil du temps, plusieurs mécanismes ont été développé pour rendre plus efficace l'utilisation de HTTP dans différents contexte

  • RPC : Actions
  • REST : Ressources
  • gRPC
  • GraphQL
  • WebHooks
  • Server-Sent Events
  • WebSockets

Protocole HTTP

Requête HTTP


Méthode GET vs POST

Méthode GET vs POST

GET

  • Récupérer des données
  • Paramètres via l'URL `/products?query=keyboard&sort=asc

POST

  • Envoyer des données
  • Paramètres via l'URL disponible ET via le body
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
    • application/octet-stream

Exemples POST

Réponse HTTP


Status HTTP

Status HTTP

  • 1XX Information
  • 2XX Succès
  • 3XX Redirection
  • 4XX Erreur du client
  • 5XX Erreur du serveur

Status Codes


Références

Démos!

Go

Démos

Protocole HTTP

HTTP est un protocol au format texte, il est possible de le tester avec un client TCP comme telnet. Le service HTTP Bin permet de tester plusieurs types de requêtes-réponses HTTP.

telnet httpbin.org 80
...
Trying 34.227.213.82...
Connected to httpbin.org.
Escape character is '^]'.

GET / HTTP/1.1
Host: httpbin.org

...

GET /xml HTTP/1.1 # Plusieurs formats: /json, /html
Host: httpbin.org

...

POST /anything?recipient=-1&subject=coucou! HTTP/1.1
User-Agent: telnet/demo
Content-Type: text/plain
Host: httpbin.org
Content-Length: 13

allo le monde

...

Pour élaborer des requêtes plus complexes, ils existe des clients HTTP spécialisés comme cURL, httpie, Insomnia.rest ou l'extension VS Code Thunder Client.

Ce type d'outil est très utile pour expérimenter et déboguer les requêtes-réponses lors du développement d'un service web.

Sinatra

Sinatra est une librairie offrant un ensemble de fonctionnalités essentielles pour développer un service web HTTP robuste avec Ruby.

Inclure la librairie

require "bundler/inline"

gemfile do
    source "http://rubygems.org"
    gem "sinatra-contrib"
    gem "webrick"
end

require 'sinatra'
require 'sinatra/reloader' if development?

# -contrib contient plusieurs extensions pratiques
# https://sinatrarb.com/contrib/

puts("Hello Sinatra!")

Démarrer le serveur

L'affichage à la console apparaîtra dans la fenêtre d'exécution du serveur.

ruby server.rb

#  ruby {FILENAME}.rb [-h] [-x] [-q] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
#  
#  Options:
#  
#  -h  help
#  -p  set the port (default is 4567)
#  -o  set the host (default is localhost in development)
#  -e  set the environment (default is development)

Tester

ss -tlnp4

# Pour voir les connexions actives: adresse, port, processus
# https://man7.org/linux/man-pages/man8/ss.8.html

# Un seul processus pour un port peut exister à la fois
# pour terminer un processus existant via le pid

kill -9 {PID}
  • Ouvrir http://{IP}:4567 dans votre navigateur web
  • Envoyer une requête avec Thunder Client pour tester votre configuration Sinatra

Routes Sinatra

server.rb

require "bundler/inline"

gemfile do
    source "http://rubygems.org"
    gem "sinatra-contrib"
    gem "webrick"
end

require 'sinatra'
require 'sinatra/reloader' if development?

#
# REQUETES
#

# Chaque URL accessible dans l'application est une ROUTE

get "/" do
  "Hello from Sinatra!"
end

get "/about" do
  "This app doesn't do much..."
end

# On peut recevoir des parametres

# Dans la QUERY STRING
# GET ou POST /greetings-query?name=james
post "/greetings-query" do
  name = params["name"]
  "Hello #{name}!"  
end

# Dans le BODY
# POST /greetings-body
post "/greetings-body" do
  name = request.body.read 
  "Hello #{name}!" 
end


#
#  REPONSES
#  GET ou POST
#

# On doit retourner une String ou un item Enumerable
# qui renvoie uniquement des string

get "/response-text" do
  "Texte brut"
end

get "/response-array" do
  # ["1", "2", "3"]

  [1, 2, 3].map do |v|
    v.to_s
  end
end

# Le JSON est tres flexible
# pour representer des données complexes
# en format texte

get "/response-array-json" do
  [1, 2, 3].to_json
end

get "/response-hash" do
    # Version longue
    # { 
    #   "firstname" => "James",
    #   "lastname" => "Hoffman"
    # }.to_json

  {
    firstname: "James",
    lastname: "Hoffman"
  }.to_json
end

get "/response-file" do
  send_file("data.txt")
end

💻 Multiplicator

Créer un service web qui génére la table de multiplication d'un nombre reçu en paramètre. Valider que le nombre est présent et un entier supérieur à 0, sinon retourner un message d'erreur.

  • Utiliser les paramètres d'URL et retourner le résultat selon le format texte ci-dessous
GET /?number=...X...

===

1 * X = 1X
2 * X = 2X
3 * X = 3X
...
X * X = XX

~~~ Si pas entier > 0

Fournir un entier supérieur à 0!
  • Dans une autre route, fournir le nombre dans le body, et retourner le résultat en JSON
POST /multiplicator

...X...

===

[
    {
        "multiplicand": 1,
        "multiplier": X, 
        "product": 1X
    },
    {
        "multiplicand": 2,
        "multiplier": X, 
        "product": 2X
    },
    {
        "multiplicand": 3,
        "multiplier": X, 
        "product": 3X
    },
    ...,
    {
        "multiplicand": X,
        "multiplier": X, 
        "product": XX
    },
]

~~~ Si pas entier > 0

Fournir un entier supérieur à 0!