LIFWEB TP4 - Programmation asynchrone en JavaScript, l’API GitHub
Introduction
On souhaite réaliser une application qui vérifie les projets GitHub d’une liste, pour savoir s’ils sont toujours actifs ou pas. On donne :
- Le fichier github-verify.html.
- Le fichier github-verify.js.
La page de départ contient un bouton, une barre de progression, un span
pour un compteur et une zone d’affichage Output. On donne une capture ci-après, dans laquelle on a vérifié les projets du fichier TheBody983-starred.json
.
On voit que quatre projets sont toujours OK, mais qu’un est KO (le projet n’existe pas sur GitHub). La barre de progression se remplie au fur et à mesure que l’on détermine l’état des projets, on peut le voir sur la démonstration YouTube (avec une version légèrement différente de l’interface et quelques explications).
Fonctionnalités
Avec l’ensemble des exercices, les fonctionnalités suivantes seront réalisées :
- Téléchargement de l’index des projets.
- Affichage des informations détaillées des projets.
- Mise à jour de la barre de progression.
- Lancement des requêtes en parallèle.
- Accès à l’API GitHub.
- Authentification GitHub.
- Bouton d’arrêt des requêtes.
- Mise en forme CSS.
Exercice -1 (PRÉPARATION) : environnement de développement
À partir de ce TP et dans tous les suivants, on suit les recommandations du CM5.
- Copier le fichier package.json à la racine de votre dossier de travail pour cette UE
- Typiquement, créez au moins un dépôt GitHub/GitLab pour cette UE et y mettre
package.json
à la racine.
- Typiquement, créez au moins un dépôt GitHub/GitLab pour cette UE et y mettre
- Installer ses dépendances avec
npm install
(oupnpm install
).- Ce sont essentiellement des outils de développement qui vous éviteront des erreurs et vous rendront plus productifs.
Configurer votre VSCode avec les plugins suivants :
- ESlint https://eslint.org/ (VSCode, Open-VSX) ;
- Prettier https://prettier.io/ (VSCode, Open-VSX) ;
- HTML https://htmlhint.com/ (VSCode, Open-VSX) ;
- Markdown markdownlint (VSCode, Open-VSX) ;
- HTML CSS Support (VSCode, Open-VSX) ;
- Live Server https://ritwickdey.github.io/vscode-live-server/ (VSCode, Open-VSX).
Le fichier package.json fournit une configuration de départ pour ESlint et Prettier qu’il faudra suivre. Pour tester votre configuration, ouvrez un des TPs précédents, vous devriez voir du rouge et des changements lors du formatage automatique.
⚠️ On attend désormais dans ce TP et les suivants, un code formaté et, sauf exception, sans warnings des linters. ⚠️
Exercice 0 (PRÉPARATION) : barre de progression
Une barre de progression <progress>
(MDN) accompagnée d’un <span>
est présente dans la page. Cette barre permet d’indiquer l’état d’avancement de la vérification. Exécuter le script suivant ligne par ligne pour comprendre le fonctionnement :
$progressBar.max = 3;
$progressBar.value = 0;
$progressBar.value = 1;
$progressBar.value = 2;
$progressBar.value = 3;
Écrire les fonctions setProgress(total)
pour initialiser l’affichage et updateProgress()
pour le faire évoluer d’un cran. Avec setInterval
écrire une fonction qui incrémente la barre de 1/n à chaque seconde pendant n secondes.
Exercice 1 : vérification de projets GitHub
Les fichiers json
fournis sont de tailles croissantes et contiennent des projets invalides :
- TheBody983-starred.json : 6 projets
- Webcretaire-starred.json : 40 projets
- romulusFR-starred.json : 307 projets
Quand on clique sur le bouton $goButton
, dans la fonction downloadAndCheck(event)
à compléter, il faut :
- Télécharger le fichier JSON choisi par le
$fileSelector
avecfetch()
(MDN). - Pour chacun des liens contenus, il faut faire une nouvelle requête de type
HEAD
avec la fonctioncheckLinkAlive(uri)
à compléter. - Au fur et à mesure que les projets répondent, il faut :
- Incrémenter la barre de progression de la page avec
updateProgress()
. - Remplir le contenu de
$output
avec la fonction avecdisplayLink(link)
.
- Incrémenter la barre de progression de la page avec
Limites du nombre de requêtes
⚠️ Vous êtes limités sur le nombre de requêtes que vous pouvez-faire. Pour l’instant, limitez-vous au plus petit des fichiers TheBody983-starred.json
. Cette limitation sera levée dans l’exercice 4. ⚠️
Requêtes CORS
☣️ Le navigateur limite les requêtes autorisées via le mécanisme CORS où le serveur déclare quels sont les domaines autorisés à exécuter du JavaScript. ☣️ Ainsi :
- Un
fetch
sur https://github.com/orodio/harness :- ✅ est autorisé depuis le navigateur si vous êtes sur
https://github.com
(ou un nom d’hôte autorisé par GitHub). - ❎ est interdit depuis le navigateur si vous êtes sur votre propre serveur de développement
http://localhost
(ou un nom d’hôte que GitHub n’a pas explicitement autorisé). - ✅ est autorisé depuis Node.js, car c’est le navigateur qui limite l’accès pour raison de sécurité, cette restriction n’existe pas en Node.js.
- ✅ est autorisé depuis le navigateur si vous êtes sur
- Un
fetch
sur https://api.github.com/repos/orodio/harness- ✅ est toujours autorisé depuis le navigateur comme depuis Node.js, car GitHub ne limite pas les accès à ce nom d’hôte.
Ainsi, il est nécessaire de réécrire les URLs pour transformer celles de la forme https://github.com/${USER}/${PROJECT}
(qui limite les requêtes via CORS) en celles de la forme https://api.github.com/repos/${USER}/${PROJECT}
(qui ne les limite pas). C’est ce que fait le début de la fonction checkLinkAlive(link)
fournie. Dans la console, sur l’onglet XHR
on pourra voir la liste des fetch
semblable à l’image suivante quand les requêtes passent :
Exercice 2 : Requêtes parallèles
Utiliser Promise.allSettled
(MDN) ou Promise.all
(MDN) pour lancer les requêtes de vérification en parallèle.
Vous aurez un tableau de promesses qui permettra d’afficher les informations des projets dans l’ordre du fichier json
et pas dans l’ordre d’arrivée des réponses.
Ajouter un bouton à l’interface pour choisir si on lance la vérification en parallèle 🚀 ou en série 🐢.
Exercice 3 : Détails des projets
On peut accéder aux informations de ces projets en interrogeant l’API publique https://api.github.com/repos/{owner}/{repo}
(documentation), pour obtenir par exemple le nombre d’étoiles actuels de chaque projet et sa date de création.
Améliorer l’affichage des liens de displayLink(link)
pour utiliser les informations détaillées fourni par l’API, par exemple pour y faire figurer l’évolution en nombre d’étoiles entre le fichier json
et le présent. Le nombre d’étoiles est accessible dans body.stargazers_count
et la date de création dans body.created_at
.
Exercice 4 (BONUS) : Authentification GitHub
Par défaut, sans authentification, l’API GitHub n’autorise que 60 requêtes par heure et vous recevrez des réponses HTTP 403 si la limite est atteinte :
- L’en-tête de réponse contiendra les champs
x-ratelimit-*
(doc). - Le corps de la réponse
GET
contiendra le lien https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting qui explique l’affaire.
Si vous êtes authentifié, la limite est beaucoup plus confortable. Pour utiliser l’authentification, il faut :
- Avoir un compte https://github.com/ 🤔.
- Créer un token secret sur votre compte GitHub dans les
Developer Settings
comme indiqué dans la doc. Lors de la création, ne donnez aucun droit, il suffit d’être authentifié, il ne s’agit pas de modifier votre projet ou votre compte. . - Passer ce token via l’en-tête HTTP de la forme
"Authorization: token ghp_UNE_CHAINE_ALEATOIRE"
(MDN) via les options defetch
comme indiqué ici.
Vous aurez alors 5.000 requêtes par heure et vous pourrez accéder aux status de vos projets privés.
Modifier votre projet et vérifier sur le fichier romulusFR-starred.json
que vous arrivez bien à lister tous les projets.
Exercice 5 (BONUS) : Interruption des requêtes
Une fois les requêtes fetch
lancées, on aimerait pouvoir les interrompre, en particulier s’il y en a plusieurs centaines. Pour cela, l’API propose une fonctionnalité de signal avec la classe AbortController
(MDN) et sa propriété AbortController.signal
(MDN). Il faut passer le signal en paramètre des options de fetch
pour qu’il puisse interrompre la requête (MDN).
Ajouter un bouton 🛑 à l’interface pour interrompre la vérification. Tous les liens qui ont été interrompus apparaitront KO.
Exercice 6 (BONUS) : Styles CSS
Utiliser la librairie CSS https://bulma.io/ pour un rendu moderne en affectant des classes CSS aux éléments de la page HTML et obtenir un rendu comme dans les exemples précédents.
Exercice 7 (AU LONG COURS) : Serveur CTF
Passer le troisième et le quatrième niveaux du CTF sur https://lifweb.univ-lyon1.fr/.