The same POST API call in various JavaScript libraries
By Flavio Copes
See the same POST API request written five ways in JavaScript, with XHR, the Fetch API, the Node https module, the request library, and Axios side by side.
I was testing an API using Insomnia, a very cool application that lets you perform HTTP requests to REST API or GraphQL API services.
They have a nice button that generates code to replica an API request from the app, where you design all your request data visually.
Internally it uses https://github.com/Kong/httpsnippet which is an HTTP Request snippet generator for many languages & libraries, written in JavaScript. A very cool project.
Anyway, the export had several code snippets. I want to show the same API call in different libraries.
First, here’s the API call description. I make a POST request to the api.randomservice.com website (it’s a random URL I just came up with) to the /dog endpoint.
To this endpoint I send an object with 2 properties:
{
name: 'Roger',
age: 8
}
encoded as JSON.
I also pass a content-type to set the content as application/json and an authorization header to authenticate my request with a Bearer token I was assigned through the API dashboard.
XHR
The first code example is XHR, which we can use in the browser natively, and in Node.js using https://www.npmjs.com/package/xmlhttprequest:
const data = JSON.stringify({
name: 'Roger',
age: 8
})
const xhr = new XMLHttpRequest()
xhr.withCredentials = true
xhr.addEventListener('readystatechange', function() {
if (this.readyState === this.DONE) {
console.log(this.responseText)
}
})
xhr.open('POST', 'https://api.randomservice.com/dog')
xhr.setRequestHeader('content-type', 'application/json')
xhr.setRequestHeader('authorization', 'Bearer 123abc456def')
xhr.send(data)
The Fetch API
Then we have the same code using the Fetch API. Fetch is native in the browser, and it’s built into Node.js too since version 18, so you don’t need the node-fetch package anymore.
Notice the body must be a string. If you pass the object directly, fetch() sends the text [object Object], so we call JSON.stringify() on it first:
fetch('https://api.randomservice.com/dog', {
method: 'POST',
headers: {
'content-type': 'application/json',
authorization: 'Bearer 123abc456def'
},
body: JSON.stringify({
name: 'Roger',
age: 8
})
})
.then(response => {
console.log(response)
})
.catch(err => {
console.log(err)
})
The node HTTPS module
Next up, the native https Node.js module. This is the most low level of the bunch. Notice you have to set the content-length header yourself, and it must match the number of bytes you write (24 here, the length of {"name":"Roger","age":8}). If it’s bigger than the body you send, the server keeps waiting for the missing bytes and the request hangs:
const http = require('https')
const options = {
method: 'POST',
hostname: 'api.randomservice.com',
port: null,
path: '/dog',
headers: {
'content-type': 'application/json',
authorization: 'Bearer 123abc456def',
'content-length': '24'
}
}
const req = http.request(options, res => {
const chunks = []
res.on('data', chunk => {
chunks.push(chunk)
})
res.on('end', () => {
const body = Buffer.concat(chunks)
console.log(body.toString())
})
})
req.write(JSON.stringify({ name: 'Roger', age: 8 }))
req.end()
The request library (deprecated)
Here is the same call using the request Node library. It was everywhere when I wrote this post, but the package was deprecated in 2020 and its last release is 2.88.2. It still installs and works, so you’ll find it in lots of older code. Don’t pick it for a new project:
const request = require('request')
const options = {
method: 'POST',
url: 'https://api.randomservice.com/dog',
headers: {
'content-type': 'application/json',
authorization: 'Bearer 123abc456def'
},
body: { name: 'Roger', age: 8 },
json: true
}
request(options, (error, response, body) => {
if (error) throw new Error(error)
console.log(body)
})
Axios
Here is the same using Axios, a popular library for both Node and the browser. Axios has been on version 1.x since 2022, and the API below hasn’t changed:
const axios = require('axios')
axios
.post(
'https://api.randomservice.com/dog',
{ name: 'Roger', age: 8 },
{
headers: {
'content-type': 'application/json',
authorization: 'Bearer 123abc456def'
}
}
)
.then(res => {
console.log(res.data)
})
.catch(error => {
console.error(error)
})
Install it with:
npm install axios@1Want me to talk about your product? You can sponsor this site.
Related posts about js: