Javascript Fetch API equivalent in Java for Http requests? - javascript

I am currently learning about Threads in Java. I wanted to know what the standard protocol would be when making Http Requests in Java that would be similar to the code I have below, which uses Javascript Fetch API and asynchronous programming. For example, if I was using the Fetch API in Javascript to first make a GET request to grab some data from a REST endpoint that I would later use to make a POST request (as seen in the code below), I would need to use a Callback function or Promise (like below) to wait until that first request has retrieved its data for the second request to then proceed. Obviously, if I did not use Promises or nest the second Http POST in the first Fetch method (GET) below, and wrote two separate Fetch API calls (one for GET, one for POST, sequentially one after other aka top-to-bottom), both calls would "fire-off" simultaneously and the second POST request wouldn't have the data it needs to make a successful POST.
const myHttpGETandPOSTmethod = () => {
// First Http request goes here
fetch('http://example.com/movies.json', {
method: 'GET',
headers: // Some headers here,
})
.then(response => response.json())
.then(data => {
console.log(data))
// Nest the second Http request inside here. It only runs after 1st request completes
return fetch('http://example.com/movies.json', {
method: 'POST',
headers: // Some headers here,
body: JSON.stringify(body);
})
.then((response) => response.json())
.then((data) => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
})
}
So then, if I were using something like the Apache HttpClient https://hc.apache.org/httpcomponents-client-4.5.x/quickstart.html library in Java, would the standard procedure be to "spin-up" another Thread (besides the main thread) to execute the GET request and then do a thread.join() such that after the first thread completes, then the second request can fire-off its own Thread?
Would I need to use a Callable instead of Runnable so that I can save the HttpEntity data response of the first GET request?
I guess I'm just trying to understand the best way to implement the scenario I posed above regarding an HTTP GET request that is needed to make a subsequent POST request, while both fires asynchronously such that they do not block the main thread.
You can make a basic GET request using the apache Http Library as such (POST is also very similar):
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://targethost/homepage");
CloseableHttpResponse response1 = httpclient.execute(httpGet);
try {
System.out.println(response1.getStatusLine());
HttpEntity entity1 = response1.getEntity();
// Save the response body to a string
String body = EntityUtils.toString(entity1, StandardCharsets.UTF_8);
System.out.println(body);
EntityUtils.consume(entity1);
} finally {
response1.close();
}
Or am I on the wrong approach here and looking at this incorrectly? I believe the Http library in Apache offers both synchronous and asynchronous Http calls? or should I be using a newer library for Http in Java?

Related

Route that is executed within another route in Node.js is not being executed

Good Evening,
I have a function that contains a route that is a call to the Auth0 API and contains the updated data that was sent from the client. The function runs, but the app.patch() does not seem to run and I am not sure what I am missing.
function updateUser(val) {
app.patch(`https://${process.env.AUTH0_BASE_URL}/api/v2/users/${val.id}`,(res) => {
console.log(val);
res.header('Authorization: Bearer <insert token>)
res.json(val);
})
app.post('/updateuser', (req, ) => {
const val = req.body;
updateUser(val);
})
app.patch() does NOT send an outgoing request to another server. Instead, it registers a listener for incoming PATCH requests. It does not appear from your comments that that is what you want to do.
To send a PATCH request to another server, you need to use a library that is designed for sending http requests. There's a low level library built into the nodejs http module which you could use an http.request() to construct a PATCH request with, but it's generally a lot easier to use a higher level library such as any of them listed here.
My favorite in that list is the got() library, but many in that list are popular and used widely.
Using the got() library, you would send a PATCH request like this:
const got = require('got');
const options = {
headers: {Authorization: `Bearer ${someToken}`},
body: someData
};
const url = `https://${process.env.AUTH0_BASE_URL}/api/v2/users/${val.id}`;
got.patch(url, options).then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});
Note: The PATCH request needs body data (the same that a POST needs body data)

When to set the headers explicitly when making HTTP request in NodeJS application

So I was having a look at a codebase of a NodeJS application and there were some specific functions making HTTP requests to the backend. To be exact, those functions were making a GET request to the backend and one thing that I found confusing was that in some of the functions, the headers were mentioned explicitly whereas, in some other functions who were making the GET request, there was no mention of headers (i.e. headers were not being set explicitly). Below is an example:
In the code below, the function is making a GET request and there's no mention of headers (i.e. the headers are not being set explicitly):
// Method for fetching a single post from the backend on the basis of the post ID
export const singlePost = (postID) => {
return fetch(http://localhost:8080/post/${postID}, {
method: "GET",
})
.then((response) => {
return response.json();
})
.catch((error) => {
console.log(error);
});
};
In the code below, the function is making a GET request and the headers are being set explicitly:
// Helper Method for making the call to the backend and fetching all their details of all the posts
export const list = (page) => {
return fetch(http://localhost:8080/posts/?page=${page}, {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
})
.then((response) => {
return response.json();
})
.catch((error) => console.log(error));
};
Now coming to the main question, could someone please explain to me when are we supposed to set the headers explicitly not only in just GET request but in other general HTTP requests as well (i.e. POST, PUT, OPTION etc).
It would be really great if some could refer a source or explain this concept here. Thanks!
HTTP request header is the information, in the form of a text record, that a user's browser sends to a Web server containing the details of what the browser wants and will accept back from the server. The request header also contains the type, version and capabilities of the browser that is making the request so that server returns compatible data.
Check this https://code.tutsplus.com/tutorials/http-headers-for-dummies--net-8039

Electron Restful Api Without react or any other express

I was going through electron js but the problem that I'm facing is in writing restful API. There are hardly any resources that show utilization of API without react.js, express and falcon vue.js. I wrote python API to add two numbers just for testing but I'm clueless about how to consume those restful API in electron without any other language such as react/express/falcon as it would increase my learning curve.
Help appreciated.
note: My API is hosted
There are two built-in methods that you can use instead of using frameworks like axios, jQuery Ajax, ...
Fetch:
Using Fetch API is really simple. Just pass the URL, the path to the resource you want to fetch, to fetch() method.
simple GET method:
//simple GET method
fetch('/js/users.json')
.then(response => {
// handle response data
})
.catch(err => {
// handle errors
});
other methods like POST, DELETE,...:
// some data to post
const user = {
first_name: 'John',
last_name: 'Lilly',
job_title: 'Software Engineer'
};
// options of fetch
const options = {
method: 'POST',
body: JSON.stringify(user),
headers: {
'Content-Type': 'application/json'
}
}
fetch('https://reqres.in/api/users', options)
.then(response => {
// handle response data
})
.catch(err => {
// handle errors
});
XML HttpRequest:
XMLHttpRequest is a built-in browser object that allows to make HTTP requests in JavaScript.
Create XMLHttpRequest:
let xhr = new XMLHttpRequest();
Initialize it, usually right after new XMLHttpRequest:
xhr.open(method, URL, [async, user, password])
method – HTTP-method. Usually "GET" or "POST".
URL – the URL to request, a string, can be URL object.
async – if explicitly set to false, then the request is synchronous, we’ll cover that a bit later.
user, password – login and password for basic HTTP auth (if required).
Send it out.
xhr.send([body])
This method opens the connection and sends the request to server. The optional
body parameter contains the request body.
Some request methods like GET do not have a body. And some of them like POST
use body to send the data to the server. We’ll see examples of that later.
Listen to xhr events for response.
These three events are the most widely used:
load – when the request is complete (even if HTTP status is like 400 or 500), and the response is fully downloaded.
error – when the request couldn’t be made, e.g. network down or invalid URL.
progress – triggers periodically while the response is being downloaded, reports how much has been downloaded.
xhr.onload = function() {
alert(`Loaded: ${xhr.status} ${xhr.response}`);
};
xhr.onerror = function() { // only triggers if the request couldn't be
made at all
alert(`Network Error`);
};
xhr.onprogress = function(event) { // triggers periodically
// event.loaded - how many bytes downloaded
// event.lengthComputable = true if the server sent Content-Length
// header
// event.total - total number of bytes (if lengthComputable)
alert(`Received ${event.loaded} of ${event.total}`);
};

Processing fetch response - JS

I have the response after GET-request with fetch. I know that this response will return an Array. When I process it with .json() - everything is fine. But when I try to process same response with .formData()- it fails.
Here's the code:
fetch(fullPath)
.then(response => response.json())
.then((allData) => {
console.log(allData);
})
.catch((e) => console.log(e));
same one with response.formData() doesn't work.
So the question is - why we are not able to process the promise in first "then" with .formData() if the off. doc says that formData() is also acceptable method for extracting a body from the response ?
The formData() method will return an error if the response is not having the multipart/form-data type. It should have key=value entries. See this question where someone asks about designing a response with that format.
Something similar happens if you call the json() method on a response that is not valid JSON: that also triggers an exception.
Since multipart/form-data is rarely used as response content type, the formData() method is not often used either. The documentation on MDN mentions it has some use for service workers:
Note: This [method] is mainly relevant to service workers. If a user submits a form and a service worker intercepts the request, you could for example call formData() on it to obtain a key-value map, modify some fields, then send the form onwards to the server (or use it locally).

Wait for token before making further ajax requests

I'm using a class that is wrapping an API. It's utilizing Axios. In order to make requests to the API I require a JWT token that's retrieved via another request using an api key:
async setAuthorizationHeader() {
const res = await this.Axios.post('/login', {
api_key: ''
});
this.AuthToken = res.data.token
this.Axios.defaults.headers.common['Authorization'] = `Bearer ${res.data.token}`
}
The class is instantiated once the script is loaded and setAuthorizationHeader method is run within the constructor, so it sends out a login request at the start. My problem is that if I want to run another API call on page load, I can't as I'll receive a 401 since we haven't gotten the token yet.
Here's another method within my class that I would also be running on page load:
async getPromotions() {
const response = await this.Axios({
method: 'POST',
url: '/promotions',
data: {
...this.baseData,
}
})
return response.data
}
Is there any way to wait for the authorization step to complete before I run the getPromotions request?
You can store promise that is about token's fetching as part of your API object.
describe all your other API calls like
API.tokenLoadingPromise.then(token => // making call with axios
This way you would ensure all your calls are executed only after token is retrieved.

Categories