axios.all concurrent request GET or POST only - javascript

Going through the axios docs, I'm trying to figure out if the axio.all construct for making concurrent requests works when the request are not all get request i.e can it work with a mix of GET and POST requests.

You can try performing multiple requests with your Axios client and using Promise.all to wait on the result of all your requests.
Here's an example using JavaScript:
const promiseGet = axios.get('/user?ID=12345')
const promisePost = axios.post('/user', { some: data })
const [responseGet, responsePost] = await Promise.all(promiseGet, promisePost)
Note that you should handle the possible errors (it's not described in the example above!)

Related

How I can mock an incoming http request in jest using node.js http?

I am making a handler library named handle_http.js:
module.exports.redirectHttpToHttps = (db,req,res)=>{
const sql = "SELECT * from redirect where use_in_http = 1 and exact_match = 1 and url_from = ? and exact_match=1 LIMIT 1";
// redirection logic
}
And I made a http server where consumes the library:
const http = require('node:http');
// A simple database connection generator
const db = require('./db.js');
const handler = require('./handle_http.js');
http.createServer((req,res){
handler.redirectHttpToHttps(db,req,res);
});
http.listen(80);
But before running into an actual code, I want to make some unit tests using jest (test_redirect.jest.js):
const db = require('../src/db.js');
const redirect = require('../src/handle_http.js');
test("redirect to https",()=>{
const dbHandler = db(':memory:');
database.exec(`
INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
`,function(error){ err_callback(error); });
// need to make fake request so I can call the `redirectHttpToHttps`
redirect.redirectHttpToHttps(db,/*mocked_request*/,/*some way to assert the response*/)
});
As you can see, I am able to populate an in-memory database with fake data, but I do not know how:
How I can make a fake an incoming http request.
How I can assert that http response has appropriate status code and headers
The provided example does not cut in my case because I need to test the http handling logic in my own http server written in nodejs.
An approach is to use the supertest and create an http server on the fly:
const http = require('node:http');
const request = require('supertest');
const db = require('../src/db.js');
const redirect = require('../src/handle_http.js');
test("redirect to https",(done)=>{
const dbHandler = db(':memory:');
database.exec(`
INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
`,function(error){ done(error); });
const server = http.createServer((req,res)=>{
redirect.redirectHttpToHttps(dbHandler,req,res)
});
request(server)
.get('/mytest')
.set('Host','google.com')
.expect(301,done);
});
Pay attention into the lines:
request(server)
.get('/mytest')
.set('Host','google.com')
.expect(301,done);
Using request function comming from supertest I provide a server instance that does not listen to any port:
const server = http.createServer((req,res)=>{
redirect.redirectHttpToHttps(dbHandler,req,res)
});
During testing, you can avoid the https at all and create pure non-ssl servers that call the http handling function you want to perform.
Miscelanous
Also, your code has an error at section:
database.exec(`
INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
`,function(error){ err_callback(error); });
Function err_callback is not defined. Therfore I used the jest's done function as defined into documentation
So the refactored part of the test is:
database.exec(`
INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
`,function(error){ done(error); });

Handling non JSON API in Javascript

So I am trying to get a circulating supply number of a token and use the API to do a further calculation with it.
All I could find was people handling JSON outputs but this is just a plain output:
https://avascan.info/api/v1/supply?q=circulatingSupply
Anyone that can help me how I can fetch this amount and use it to further do calculations with?
You can use the fetch API, which have a text method on it's response, for example:
const BASE_URL = 'https://avascan.info/api/v1/supply?q=circulatingSupply';
async function getCirculatingSupply() {
const response = await fetch(BASE_URL);
const data = await response.text();
return Number(data);
}
getCirculatingSupply().then(console.log);
Keep in mind that maybe you will have problems with CORS, as I had testing this API, so maybe you will need to use a proxy server like cors-anywhere to bypass this problem.

Request to API and waiting to answer

I need to send GET request username=alison&date=2021 to file file.phpand send requests every 200 ms if I don't get one of two possible responses "yes" or "no", resend request needed to get right answer no blank and not error.
If get "yes" "no" do functions.
when receiving responses, perform different actions
function after receiving yes
function after receiving no
I'm not 100% sure what you're asking for here, but here is my method based on my own interpretation of your question using a call from GitHub's API. We are using fetch to pull the data. Our .then is our resolve, and our .catch is our reject.
const url = 'https://api.github.com/users'
const callApi = function(fetchUrl){
fetchUrl = url
fetch(fetchUrl)
.then(response=>{
return response.json(); // Turn data to JSON
})
.then(data=>{ // If it was successful, this below will run
console.log(data) // Do whatever you want with the data from the API here
})
.catch(err=>{ // If it was unsuccessful, this below will run
console.log(err); // Console log the error
setTimeout(callApi(url), 200); //If it failed, try again in 200ms
})
}
callApi(url) // Initial function call
Some things to note: If you're using an API that limits the number of calls you can make in a day/month, this will eat up through those allotted requests really quickly.

How to send batch axios GET requests by iterating +1

How do I send bulk HTTP GET requests using Axios, for example:
let maxI = 3000;
let i = 0;
do{
i = i + 1 ;
await exampleUrl = axios.get(`https://hellowWorld.com/${i}`);
} while (i < maxI);
How will I be able to receive the data from all the provided URLs and can this be merged into a single variable? And how can I make sure that this gets executed quickly?
I know about axios.all, but I don't know how to apply it in my case.
Thank you in advance.
You can do something like this but be careful, servers will reject your request if you make them in bulk to prevent DDOS and this also doesn't guarantee that all the requests would return successfully and you will receive all the data, here is the snippet for it:
import axios from "axios";
const URL = "https://randomuser.me/api/?results=";
async function getData() {
const requests = [];
for (let i = 1; i < 6; i++) {
requests.push(axios.get(URL + i));
}
const responses = await Promise.allSettled(requests);
console.log(responses);
const result = [];
responses.forEach((item) => {
if (item.status === "rejected") return;
result.push(item.value.data.results);
});
console.log(result.flat());
}
getData();
AFAIK, it is impossible to increase the speed/reduce the time taken to complete your batch requests unless you implement a batch request handling API on server which would reduce both number of requests handled by the server and the number of requests made by the browser. The solution I gave you is just to demonstrate how it could be done from client side but your approach is not an optimal way to do it.
There is a different limit for number of parallel requests that can be made to a single domain for different browsers because of which we cannot reduce the time taken to execute queries.
Please read through these resources for further information they will be of great help:
Bulk Requests Implementation
Browser batch request ajax
Browser request limits
Limit solution

ReactJS: how to make two backend requests at once?

Is it possible to make two backend requests at once from react?
The code below is the first backend call. The post request gets send to the backend and then I would like to do another request. Is it possible at all? Or do I have to wait for the backend response until the next request could be made?
What I basically want is to get information about how many files have been uploaded. The upload could take 3 minutes and the user right now only sees a loading icon. I want to additionally add a text like "50 of 800 Literatures uploaded" and 10 seconds later "100 of 800 litereratures uploaded".
This is basically my code :
class ProjectLiterature extends Component {
constructor(props) {
super(props);
this.state = {
isLoading:"false",
}
}
addLiterature(data, project_name) {
this.setState({ isLoading:true }, () => {
axios.post("http://127.0.0.1:5000/sendLiterature", data })
.then(res => {
this.setState({ isLoading: false })
})
})
}
If both requests do not depend on each other, you can make use of JavaScript's Promise.all() for the above purpose.
const request1 = axios.get('http://127.0.0.1:5000/sendLiterature');
const request2 = axios.get(url2);
Promise.all([request1,request2]).then([res1, res2] => {
// handle the rest
}).catch((error) => {
console.error(error);
// carry out error handling
});
If the second request relies on the response of the first request, you will have to wait for the first request to be completed as both requests have to be carried out in sequence.
const res = await axios.get('http://127.0.0.1:5000/sendLiterature');
// carry out the rest
You can see axios docs for this purpose, they support multiple requests out of box.
You can use Promise.all instead of axios.all as well but if one of requests fails then you won't be able to get response of successful calls. If you want get successful response even though some calls fails then you can use Promise.allSettled.

Categories

Resources