Did you ever wonder what is the best and clean way to make JavaScript REST API calls? What about in a big project, where you are making hundreds of them?
I had this question too late in my projects, after a lot of code was already written. It is much better to know early which method to choose, it will give you a lot less headaches later.
As you may know, there are a lot of options to call API from JavaScript. Some of them are XMLHttpRequest, jQuery, fetch and so one. I am going to talk about the fetch method here because it looks cleaner in our code.
Using fetch is very simple. A http request looks typically like this:
fetch('[https://jsonplaceholder.typicode.com/todos/1](https://jsonplaceholder.typicode.com/todos/1)')
.then(response => response.json())
.then(json => console.log(json));
As you can see, it is pretty simple to make a get request. But what happens when we want to make a post request. Let's see:
fetch('[https://jsonplaceholder.typicode.com/todos/1](https://jsonplaceholder.typicode.com/todos/1)',
{method: “POST”, body: JSON.stringify(data)})
.then(response => response.json())
.then(json => console.log(json));
Things are starting to look pretty ugly already. Similar, put and delete methods will look the same.
Ok, we need to do something with this. First of all, let's imagine that my base rest api url is something like *https://my-url/v1/* and if I want to get all users from the server I would have to call *https://my-url/v1/users*. As you can see, I will always use *https://my-url/v1/* in my code. So, if I have to make hundreds of requests, my code will be polluted with this string.
Also, what happens if in the future I will make an upgrade to my application and I will need to upgrade also my rest base url from v1 to v2. I will have to search everywhere in my application and replace those strings.
First option
My first option would be to create a main.js that I will import in every .js file and in this file I would declare my base url string. Let's see how it would look:
main.js
const baseUrl = '[*https://my-url/v1/](https://my-url/v1/)*';
users.js
fetch(baseUrl + 'users')
.then(response => response.json())
.then(json => console.log(json));
It is looking better now but I would still duplicate code and would have .then(…) and baseUrl constant everywhere in my project. So, I would like to do something more generic. Also, what happens if I want to add some authentication headers to my requests. The code will look like this:
const baseUrl = '[*https://my-url/v1/](https://my-url/v1/)*';
const authHeaders = {Authorization: 'Bearer ' +
$.cookie('jwtToken'), 'Content-Type': 'application/json'};
fetch(baseUrl + 'users', {method:'GET', headers: authHeaders)
.then(response => response.json())
.then(json => console.log(json));
As you can see, the code can get nasty very quickly as I need more on more options.
Best option
The best option that works for me it's the following one. In my main.js file, I would define four methods, for **put,post,get **and delete and use them directly for window object everywhere in my code. So, in my main.js file I would have the following:
const urlLocation ='[*https://my-url/v1/](https://my-url/v1/)*';
const authHeaders = {Authorization: 'Bearer ' +
$.cookie('jwtToken'), 'Content-Type': 'application/json'};
window.postJson = function (url, data) {
return fetch(urlLocation + url, {method: “POST”, headers:
authHeaders, body: JSON.stringify(data)}).then((res) => res.json());
}
window.getJson = function (url) {
return fetch(urlLocation + url, {method: “GET”, headers: authHeaders})
.then((res) => res.json());
}
window.deleteJson = function (url) {
return fetch(urlLocation + url, {method: “DELETE”, headers: authHeaders})
.then((res) => res.json());
}
window.putJson = function (url) {
return fetch(urlLocation + url, {method: “PUT”, headers: authHeaders})
.then((res) => res.json());
}
And in my project, if I need to make a get call to get all users all I have to do is:
const alUsers = await getJson(allUsers+'users').then( (res) => { return res; } );
As you can see, this is a much cleaner and easy to maintain way of making rest api calls. Now, I have all my logic in just one place and I can easily change my base url location or add / remove headers.
PS: If you ever need an uptime monitoring tool, just check RoboMiri. The best free uptime monitoring service.