Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requêtes en double à l'API #71

Closed
florimondmanca opened this issue Feb 15, 2022 · 0 comments · Fixed by #73
Closed

Requêtes en double à l'API #71

florimondmanca opened this issue Feb 15, 2022 · 0 comments · Fixed by #73
Labels
bug Something isn't working technical

Comments

@florimondmanca
Copy link
Collaborator

florimondmanca commented Feb 15, 2022

Description du bug

Dans #48, on a configuré un système de routing entre le client et le serveur d'API.

Ce système fonctionne, mais il y a un problème : les requêtes à l'API effectuées lors du load sont dupliquées.

Comportement attendu

Lors de l'ouverture de la page de catalogue, 1 seule requête d'API doit être reçue par le serveur, par le serveur Svelte (SSR).

En particulier, le navigateur ne doit pas faire de requête à l'API lors du chargement de la page, en vertu de l'usage de la technique load / hydration.

Comportement réel

Les requêtes sont faites en 2 exemplaires : 1 par le serveur Svelte (SSR), 1 par le navigateur une fois la page chargée.

Pour reproduire

  • Ouvrir staging dans le navigateur : http://51.159.187.137/
  • Se connecter à l'instance staging en SSH et consulter les logs serveur au fil de l'eau : tail -f /var/log/server.out.log
  • Ouvrir la console web
  • Recharger la page
  • Constater dans les logs que 2 requêtes identiques ont été faites :
2022-02-15 11:18:59,832 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-02-15 11:18:59,833 INFO sqlalchemy.engine.Engine SELECT dataset.id, dataset.title, dataset.description 
FROM dataset
2022-02-15 11:18:59,833 INFO sqlalchemy.engine.Engine [cached since 395.1s ago] ()
2022-02-15 11:18:59,842 INFO sqlalchemy.engine.Engine ROLLBACK
INFO:     92.158.30.170:0 - "GET /api/datasets/ HTTP/1.1" 200 OK
2022-02-15 11:19:00,053 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-02-15 11:19:00,054 INFO sqlalchemy.engine.Engine SELECT dataset.id, dataset.title, dataset.description 
FROM dataset
2022-02-15 11:19:00,054 INFO sqlalchemy.engine.Engine [cached since 395.3s ago] ()
2022-02-15 11:19:00,062 INFO sqlalchemy.engine.Engine ROLLBACK
INFO:     92.158.30.170:0 - "GET /api/datasets/ HTTP/1.0" 200 OK
  • Constater que le navigateur a en effet lui aussi fait une requête. Par ex la console web affiche :
XHR GET http://51.159.187.137/api/datasets/ [HTTP/1.1 200 OK 33ms]

Analyse

La technique de hydration* de Svelte consiste à inclure dans le HTML un tag contenant le chemin de l'endpoint d'API appelé.

Cf : https://kit.svelte.dev/docs/appendix#hydration

When fetching data during SSR, by default SvelteKit will store this data and transmit it to the client along with the server-rendered HTML. The components can then be initialized on the client with that data without having to call the same API endpoints again.

On peut voir ce tag en faisant une requête en ligne de commande (hors du navigateur), pour voir le résultat "brut" envoyé par Svelte (qui est ensuite traité pour "hydrater" la page) :

$ curl localhost:3000
# Du HTML... Puis un gros blob contenant :
<script type="application/json" data-type="svelte-data" data-url="http://localhost:3579/datasets/">{"status":200,"statusText":"OK","headers":...}</script>

Si une requête côté client correspond au data-url, elle ne sera pas faite et le résultat contenu dans le <script data-type="svelte-data"> sera instantanément utilisé (hydraté).

Or on le voit, actuellement data-url chemin contient l'URL de l'API, puisque c'est bien celle-ci qui est requếtée par le serveur Svelte lors du SSR, en vertu de getApiUrl() :

export const getApiUrl = () => {
if (!browser) {
// During SSR, request the local API server directly,
// no need to travel through the Internet.
// This works in all environments - local development or live production.
return `http://localhost:${API_PORT}`;
}
// In the browser, request /api on the current domain.
// * This works in production because this will request
// https://<domain>/api/..., which is the public URL to the
// API server (as exposed via Nginx).
// * This works in development because Vite is configured
// to proxy localhost:3000/api/... to the local API server.
// (We can't just switch on `NODE_ENV` because we don't have access
// to `process.env` from here.)
return "/api";
};

Pistes de résolution

On devrait pouvoir résoudre le problème en "patchant" la data-url à la volée, grâce à un handle hook.

(Un peu du bricolage, et probablement une certaine immaturité de SvelteKit de ne pas avoir de façon "officielle" de faire cela, mais ça devrait fonctionner.)

@florimondmanca florimondmanca added bug Something isn't working technical labels Feb 15, 2022
@florimondmanca florimondmanca changed the title Requêtes en double à l'API et build local non-fonctionnel Requêtes en double à l'API Feb 15, 2022
@florimondmanca florimondmanca added this to Backlog in Outil de catalogage de données via automation Feb 15, 2022
@florimondmanca florimondmanca moved this from Backlog to Tâches en cours in Outil de catalogage de données Feb 15, 2022
Outil de catalogage de données automation moved this from Tâches en cours to Terminé Feb 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working technical
1 participant