DEV Community

SavagePixie
SavagePixie

Posted on

How to make HTTP requests with Node

If your experience is any similar to mine, the first time you had to fetch data from a JSON API on your Node server you probably wrote something like this and were disappointed it didn't work.

fetch(API_URL).then(doStuff)

It is unfortunate, but fetch doesn't work in node. Luckily, there are several other ways to make HTTP requests. There is a library called axios that is based on promises and ends up doing something similar to fetch. Today, however, I'm going to talk about the module http.

What is http?

http is Node's standard module to perform HTTP requests. The coolest part about it is that you don't need to install any dependencies to use it, just require it and you're ready to go.

const http = require('http')

There is one catch, though. http only works for HTTP, so if you're sending a request via HTTPS, then you'll need to use the module https instead.

Making a GET request

const http = require('http')

http.get(API_URL, res => {
   let data = ''
   res.on('data', chunk => data += chunk)
   res.on('end' () => console.log(JSON.parse(data))
}).on('error', err => console.error(err.message))

This executes an HTTP GET request to API_URL and gathers the data into the variable data as it receives it. Once it's finished receiving data, it parses it and logs it on the console.

If we want to make the code reusable with promises, we only need to make a function that returns a promise:

const request = url => new Promise((resolve, reject) => {
   let data = ''
   const req = http.get(url, res => {
      res.on('data', chunk => data += chunk)
      res.on('end', () => resolve({ ...res, body: JSON.parse(data))
   }).on('error', reject)
})
   .then(({ res, body }) => doStuff())

A good thing about the method .get is that it calls .end automatically, so we don't need to add it.

Making other kinds of requests

http also has the method request, which can be used to make any sort of HTTP request. Besides (or instead of) the url, it takes an object with the request's options as its first argument.

const options = {
   hostname: API_HOST,
   path: API_PATH,
   method: 'POST',
   headers: { ... }
}

const request = options => new Promise((resolve, reject) => {
   let data = ''
   const req = http.request(options, res => {
      res.on('data', chunk => data += chunk)
      res.on('end', () => resolve({ ...res, body: JSON.parse(data))
   })
   req.on('error', reject)
   req.end()
})
   .then(({ res, body }) => doStuff())

Obviously, the module http(s) can be used without promises. But I like working with promises.

Latest comments (0)