Ce que devient une requête dans un serveur
Un serveur d’application est le programme placé derrière une adresse web, qui répond aux requêtes. Il lit la requête, décide à quoi elle sert, interroge les données et renvoie une réponse.
Tous les serveurs font ces quatre travaux, quel que soit le langage. Dans cette leçon, vous en regardez un les faire.
À la fin de cette leçon
Remarque
Je peux dire ce que fait un serveur d’une requête, étape par étape, et le montrer en train d’interroger la base.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Serveur | le programme derrière une adresse, qui répond aux requêtes |
| Route | la règle qui envoie une requête vers le code qui la traite |
| Gestionnaire | le code qui répond à un genre de requête |
| Chaîne de requête | la partie d’une adresse après le point d’interrogation |
| Paramètre | une valeur envoyée à la base à part du texte SQL |
| Réponse | le statut, les en-têtes et le corps que renvoie un serveur |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Quatre étapes de la requête à la réponse
D’abord le serveur analyse la requête : sa méthode, son chemin et sa chaîne de requête. Puis il l’aiguille, en cherchant à quel gestionnaire elle est destinée.
Le gestionnaire vérifie la requête, puis interroge les données, puis répond avec un statut et un corps. Le serveur du labo est un programme nommé PostgREST. Ses routes sont les tables. Créez une table à interroger.
Donner le mot de passe à psql
export PGPASSWORD=shopAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Créer la table livres
psql -h db -U shop -c "drop table if exists livres; create table livres (id serial primary key, titre text not null, annee int not null, disponible boolean not null default true); insert into livres (titre, annee, disponible) values ('Cartes de la mer', 1998, true), ('Fleuves du monde', 2004, false), ('Trains de nuit', 2011, true); notify pgrst, 'reload schema'"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Interroger une colonne qui n’existe pas
curl -s -w "\n" "http://api:3000/livres?rien=eq.1"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Un serveur vérifie avant d’interroger
La réponse dit qu’il n’y a pas de colonne rien, avec un 400 et une raison. Le code 42703 est celui de PostgreSQL : ici, c’est la base elle-même qui a repéré le mauvais nom.
Un serveur soigneux vérifie les noms avant d’interroger les données. Une requête qui ne peut pas marcher est alors refusée tout de suite, et les mauvaises requêtes n’atteignent jamais les données. Votre devoir fonctionne ainsi.
La chaîne de requête pose la question
L’adresse /livres?disponible=eq.true&select=titre&order=id dit trois choses. Garder seulement les lignes où disponible vaut vrai. Ne rendre que la colonne titre. Mettre les lignes dans l’ordre de id.
Envoyez-la, puis posez vous-même la même question à la base, en SQL.
Envoyer la requête
curl -s -w "\n" "http://api:3000/livres?disponible=eq.true&select=titre&order=id"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Poser la même question à la base
psql -h db -U shop -At -c "select titre from livres where disponible = true order by id"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Regarder le serveur interroger la base
Le serveur a écrit ce SQL à votre place. Pour le voir, demandez à PostgreSQL de journaliser chaque requête reçue, puis lisez le journal avec le docker logs du labo. Ce réglage ne sert qu’à cette leçon, et les derniers Run le désactivent.
docker logs ne marche que dans un labo qui a sa commande Docker.
Activer la journalisation des requêtes
psql -h db -U shop -c "alter system set log_statement = 'all'" -c "select pg_reload_conf()"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Renvoyer la même requête
curl -s -o /dev/null "http://api:3000/livres?disponible=eq.true&select=titre&order=id"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lire le SQL envoyé par le serveur
docker logs --tail 30 db 2>&1 | grep -o 'SELECT "public"."livres"[^)]*' | tail -1Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Exemple travaillé : de la requête au SQL
| Partie de la requête | Ce qu’elle demande | Le SQL envoyé |
|---|---|---|
| /livres | La table livres | FROM "public"."livres" |
| disponible=eq.true | Seulement les lignes où disponible est vrai | WHERE "public"."livres"."disponible" = $1 |
| select=titre | Seulement la colonne titre | SELECT "public"."livres"."titre" |
| order=id | Dans l’ordre de id | ORDER BY "public"."livres"."id" |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Lire la valeur, envoyée à part
docker logs --tail 30 db 2>&1 | grep -o 'parameters: .*' | tail -1Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
La valeur voyage à part du SQL
Le SQL dit = $1. La valeur, t pour vrai, a été envoyée séparément : la base la traite comme une donnée, jamais comme du SQL. Voilà pourquoi une requête ne peut pas réécrire la question.
Prouvez-le. Envoyez un titre qui ressemble à une attaque, et voyez ce que fait le serveur.
Envoyer un titre qui ressemble à du SQL
curl -s -G --data-urlencode "titre=eq.x'; drop table livres; --" -w "\n" "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Voir comment il a été transmis
docker logs --tail 30 db 2>&1 | grep -o 'parameters: .*' | tail -1Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Compter les livres
psql -h db -U shop -At -c "select count(*) from livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Désactiver de nouveau la journalisation
psql -h db -U shop -c "alter system reset log_statement" -c "select pg_reload_conf()"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une erreur fréquente
Attention
Beaucoup croient qu’un serveur n’est qu’un tuyau entre le navigateur et la base. Il vérifie, décide et limite. Il doit distinguer une réponse vide d’une mauvaise requête. Aucune ligne qui correspond est un 200 avec une liste vide. Une requête qui ne peut pas marcher est un 400.
Pour aller plus loin : une question plus grande
Écrivez une requête dans le même style pour cette question. Les livres disponibles parus après 2000, du plus récent au plus ancien, avec seulement le titre et l’année. Envoyez-la avec curl.
Puis écrivez le SQL que vous attendez, et lisez le journal pour vérifier.