Comparison of some http clients for Node.js
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
README.md

README.md

HTTP Clients compared

Request Axios SuperAgent Node-Fetch
NodeJS + + + +
Browser + + +
API Callback / Stream Promise Promise-compatible Promise
Query params url / object url / object url / object url
Custom HTTP verbs + + + +
Custom HTTP headers + + + +
Default HTTP headers Connection
Host
Accept
Connection
Host
User-Agent
Accept-Encoding
Connection
Host
User-Agent
Accept
Accept-Encoding
Connection
Host
User-Agent
HTTPS + + + +
Forms + + + -
Cookies + - + -
Auto Redirect On ++ + + +
Auto Redirect Off TODO ? TODO ? TODO ? TODO ?
Basic auth (by default) + + + -

NodeJS

All platforms are available as NPM packages.

Browser

  1. You can bundle Request but it's way too big (~2 Mib) for Browser (due to NodeJS Streams etc.).
  2. Node-Fetch just emulates native fetch API.

API

Request

Supports callback and streaming APIs natively. There are external plugins for promise API.
Or just new Promise(...) ;)

TODO:

  • 404 is an "error" or not?
  • 500 is an "error" or not?
let opts = {
  url: "https://httpbin.org/get",
  qs: { id: 30 },
}

// callback
request.get(opts, (err, response, body) => {
  if (err) {
    console.log("err:", err)
  }
  else {
    console.log("code:", response.statusCode) // : number
    console.log("headers:", response.headers) // : Object
    console.log("body:", body)                // : TODO auto parsed due to mimetype?!
  }
})

// streaming
request(opts).pipe(process.stdout)

Axios

TODO:

  • 404 is an "error" or not?
  • 500 is an "error" or not?
let opts = {
  url: "https://httpbin.org/get",
  params: { id: 30 },
}

axios.get(opts)
  .then((res) => {
    console.log("code:", res.status)     // TODO type
    console.log("headers:", res.headers) // TODO type
    console.log("body:", res.data)       // TODO type
  })
  .catch((err) => {
    console.log(err.status)
  })

SuperAgent

TODO:

  • 404 is an "error" or not?
  • 500 is an "error" or not?
let url = "https://httpbin.org/get"
let opts = { id: 30 }

superagent.get(url)
  .query(opts)
  .end((err, res) => {
    if (err) {
      console.log("err:", err.status)
      console.log("err:", err.response.error)
    } else {
      console.log(res.statusCode)
      console.log(res.headers)
      console.log(res.body)
    }
})

Node-Fetch

TODO:

  • 404 is an "error" or not?
  • 500 is an "error" or not?
let url = "https://httpbin.org/get?id=30"

fetch(url)
  .then(res => {
    console.log(res.status)
    console.log(res.headers)
    return(res)
  })
  .then(res => res.json())
  .then(res => {
    console.log(res)
  }).catch(err => {
    console.log(error)
  })

Custom HTTP verbs

TODO demo

Custom HTTP headers

TODO demo

Custom HTTP verbs

Request

let opts = {
  method: "move",
  url: "https://httpbin.org/get",
  qs: { id: 30 }
}

request(opts, (error, response, body) => {
 //....
})

Axios

let opts = {
  method: "move",
  url: "https://httpbin.org/get",
  params: { id: 30 }
}

axios(opts)
  .then((res) => {
    //...
  }).catch((err) => {
    //...
  })

SuperAgent

let method = "move"
let url = "https://httpbin.org/get"
let params = { id: 30 }

superagent(method, url)
  .query(params)
  .end(function(err, res) {
    //...
})

Node-Fetch

let opts = { method: "move" }
let url = "https://httpbin.org/get?id=30"

fetch(url, opts)
  .then(
    //...
  })

Query params

All four libraries support passing query params in URL.
Node-Fetch does not support query-as-object passing.

Forms

Request

request
  .post("https://httpbin.org/post", { form: { test: "test" } })
  .pipe(process.stdout)

Axios

To perform post request with application/x-www-form-urlencoded in Axios, we need to use querystring or qs

const querystring = require("querystring")

axios
  .post(endPoints.post.url, querystring.stringify({form: {test: "test"}}))
  .then((res) => {
    response(res)
  })
  .catch((err) => {
    error(err)
  })

SuperAgent

By default SuperAgent user json, and to use application/x-www-form-urlencoded we need to invoke type(), and pass "form" to it.

superagent
  .post("https://httpbin.org/post")
  .type("form")
  .send({ test: "test"})
  .end((err, res) => {
    //....
})

Node-Fetch

To do the same in Node-Fetch we need to set headers manually, or use external libraries

fetch(endPoints.post.url, { method: "post",
                            headers: {"Content-Type": "application/x-www-form-urlencoded"},
                            body: "test=test" })
  .then(
    //....
  )

Auto Redirect On

Request adds Referer header like:

Referer: http://httpbin.org/redirect-to?url=http://httpbin.org/get

Auto Redirect Off

...

Axios, Superagent, Node-Fetch

There is no difference between normal get request, and redirected request.

Basic-auth

Request and Axios have got similar API for BasicAuth:

Request

let basicAuth = {
  method: "get",
  uri: "https://httpbin.org/basic-auth/user/passwd",
  auth: {
    user: "user",
    pass: "passwd"
  }
}

request(basicAuth, (error, response, body) => console.log(response.statusCode))

Axios

let basicAuth = {
    method: "get",
    url: "https://httpbin.org/basic-auth/user/passwd",
    auth: {
      username: "user",
      password: "passwd"
    }
  }

axios(basicAuth).then(res => console.log(res.status))

SuperAgent

superagent.get("https://httpbin.org/basic-auth/user/passwd")
  .auth("user", "passwd")
  .end((err, res) => console.log(res.statusCode))

Plugins

All these libraries have a sufficient set of plugins created by the community (for example, the implementation of the promise api for the Request). However, from this point of view, it is worth highlighting SuperAgent, which has a specialized interface for connecting plugins (https://github.com/visionmedia/superagent#plugins)

Conclusion

For these tests, I used HTTPbin.

In the process of comparing their libraries, I came to the conclusion that they all have enough positive sides to use them.

Request – despite the fact that it is not cross-platform, it undoubtedly has the most opportunities out of the box. Ability to use NodeJS streams looks attractive.

Axios – as for me has the most understandable syntax and follows the idea of "principle of least surprise".

SuperAgent – also has a fairly understandable api, but much more important is the idea of its extensibility through plugins.

Node-Fetch – good old fetch api. A small number of dependencies and a familiar interface.