Objectifs
Pouvoir Requêter en masse une API (jusqu'à 30 000 requêtes)
- en faisant n requêtes en parallèle
- en donnant la possibilité de créer des lots de requêtes
- en donnant la possibilité de pouvoir pauser l'envoie des lots
Prérequis
- nodejs
- axios pour gérer les requêtes et l'asynchrone
- async await pour gérer l'asynchrone
Le code
La vue
<div class="btn-container"> <a id="btn" class="waves-effect waves-light btn">Get all URLS</a> </div> <hr> <div id="container"></div> <pre id="result"></pre>
Le style
body { margin: 0; min-height: 100vh; background: #004d4d; } #container > div { width: 150px; margin: 10px; padding: 10px; line-height: 12px; background: #ededed; display: inline-block; border: 2px solid #fff; animation-name: fade-in; animation-fill-mode: both; animation-duration: .3s; } .teal { background: #008080; } .btn-container { margin: 10px; } .card-title { font-size: 14px !important; } @keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
Le js
Pré-requis:
- crée un package.json en local avec npm init
- installer axios avec npm install axios --save
- coder dans votre fichier nomdefichier.js
- tester le resultat dans le terminal avec `$ node nomdefichier.js`
- tester le resultat dans le navigateur en ouvrant celui-ci
// on importe axios const axios = require('axios'); let AllDatas = [], AllDatasInError = [], urls = [], waitTime = 500, // the amount of time we wait between each batch of request start = 0, step = 2, // number of url we request position = 0, nbRequest = 12; // number of request AllDatas['total'] = 0; // total of data let btn = document.getElementById('btn'); btn.addEventListener('click', function() { batchProcessing(urls); }); function createUrl() { for (let i = 1; i <= nbRequest; i++) { urls.push(`https://jsonplaceholder.typicode.com/photos/${i}`); } } createUrl(); // timer const waitFor = (ms) => new Promise(r => setTimeout(r, ms)); // parallel REQUEST with AXIOS async function getData(links) { try { const res = await axios.all(links.map(link => axios.get(link))); console.log('GetData Start time', new Date()); return res; } catch (error) { console.log('------------------------------------------'); console.log(error); } } // async function batchProcessing(urls) { const len = urls.length / step; // let result = []; console.time('batchProcessing'); console.log('batchProcessing Start time', new Date()); // use of an interceptor to edit every response axios.interceptors.response.use(function (response) { // Do something with response data let responseData = response.data; // const newVal = {}; if (responseData.id) { responseData['position'] = `${position}/${len}`; // create html element addElement(responseData); AllDatas['total'] += 1; AllDatas.push(responseData); } console.log('responseData', responseData); return responseData; }, function (error) { // Do something with response error return Promise.reject(error); }); // batch processing for(let index = 0; index < len; index ++) { var processingUrl = urls.slice(start, start + step); start += step; position += 1; console.log('position', position + ' / ' + len); console.log('processingUrl', processingUrl); // make the requests const res = await getData(processingUrl); AllDatas = AllDatas.concat(res); // break time await waitFor(waitTime); } // we are now done console.log('End timer', new Date()); console.timeEnd('getData'); // console.log('Final AllDatas', AllDatas); // document.querySelector('pre').innerHTML = AllDatas; }
/****** RENDERING THE HTML *****/ function addElement (data) { console.log('element added', data); let mainDiv = document.getElementById("container"); let newDiv = document.createElement("div"); let newContent = ` <div class="card"> <div class="card-image"> <img src="${data.thumbnailUrl}"> <span class="card-title"> Element ${data.id} </span> </div> <div class="card-content"> <p>${data.title}. (batch ${data.position})</p> </div> <div class="card-action"> <a href="${data.url}">See the source</a> </div> </div>`; // console.log('newContent', newContent); newDiv.innerHTML = newContent; mainDiv.appendChild(newDiv); }