Depuis très longtemps, la connectivité réseau est utilisé pour permettre à un programme d'exécuter une tâche sur une autre machine.
En exposant l'interface logicielle, API, via le protocole HTTP, toutes sortes de clients peuvent en bénéficier.
Au fil du temps, plusieurs mécanismes ont été développé pour rendre plus efficace l'utilisation de HTTP dans différents contexte
GET
POST
application/x-www-form-urlencoded
multipart/form-data
text/plain
application/octet-stream
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 est une librairie offrant un ensemble de fonctionnalités essentielles pour développer un service web HTTP robuste avec Ruby.
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!")
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)
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}
http://{IP}:4567
dans votre navigateur webserver.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
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.
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!
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!