npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

backendless-request

v0.13.0

Published

Simple Node.js and browser REST client

Readme

Backendless Request

npm version

Simple Node.js and Browser REST client

backendless.js => ~ 28 KB
backendless.min.js => ~ 11 KB

How to use

Install

for installation just execute the following command:

npm i backendless-request -S

Require it as a module

import BackendlessRequest from 'backendless-request';

//or

const BackendlessRequest = require('backendless-request');

Include it as a single file

Inside the installed package you can find a dist directory, where are two js files backendless-request.js and backendless-request.min.js

-|
 - dist
    |-backendless.js
    |-backendless.min.js
 

Get one of the js files into your project

<script src="/path-to-backendless-request-package/dist/backendless-request.js"></script>

you can use minimized file as well

<script src="/path-to-backendless-request-package/dist/backendless-request.min.js"></script>

After that you can use BackendlessRequest from the global scope

BackendlessRequest.get('http://foo.bar/')

As a part of the JS-SDK

Since the JS-SDK already uses the module for API requests, therefor if you use the SDK in your code you can use the Request module as well in your code without additional require, see the example below:

import Backendless from 'backendless';

Backendless.Request.get('https://foo.bar/')
  .then(result => console.log(result))
  .catch(error => console.error(error))

In the UI Builder and JS Cloud Code environment

The Backendless UI Builder and JS Cloud Code include the Backendless JS-SDK in the global scope, therefor the Request module is also available there, see the example below:


Backendless.Request.get('https://foo.bar/')
  .then(result => console.log(result))
  .catch(error => console.error(error))

Request Methods

GET

BackendlessRequest.get('https://foo.bar/')
  .then(result => console.log(result))
  .catch(error => console.error(error))

POST

BackendlessRequest.post('https://foo.bar/', { foo: 'bar', bool: true, num: 1 })
  .then(result => console.log(result))
  .catch(error => console.error(error))

PUT

BackendlessRequest.put('https://foo.bar/', { num: 123 })
  .then(result => console.log(result))
  .catch(error => console.error(error))

DELETE

BackendlessRequest.delete('https://foo.bar/foo')
  .then(result => console.log(result))
  .catch(error => console.error(error))

PATCH

BackendlessRequest.patch('https://foo.bar/foo', { bool: false })
  .then(result => console.log(result))
  .catch(error => console.error(error))

HEAD

A HEAD response has no body, so the useful part of the result are the response headers, use .unwrapBody(false) to get the whole response instead of its body

BackendlessRequest.head('https://foo.bar/foo')
  .unwrapBody(false)
  .then(result => console.log(result.status, result.headers))
  .catch(error => console.error(error))

OPTIONS

BackendlessRequest.options('https://foo.bar/foo')
  .unwrapBody(false)
  .then(result => console.log(result.headers))
  .catch(error => console.error(error))

Query Params

You can set up a request query through .query(query) method and the library will automatically add the query to request url

// RequestUrl: https://foo.bar/some-path?str=some-string&num=123&bool=true&arr=1&arr=2&arr=3&arr=4
BackendlessRequest.get('https://foo.bar/some-path') 
  .query({ str: 'some-string', num: 123, bool: true, list: [1, 2, 3, 4] })
  .then(result => console.log(result))
  .catch(error => console.error(error))

Request Body

You can send request body through the .send(body) method, but if you don't do that, the method will be called with the second argument when you call then or catch method.

BackendlessRequest.post('https://foo.bar/some-path') 
  .send({ str: 'some-string', num: 123, bool: true, list: [1, 2, 3, 4] })
  .then(result => console.log(result))
  .catch(error => console.error(error))
BackendlessRequest.post('https://foo.bar/some-path', { str: 'some-string', num: 123, bool: true, list: [1, 2, 3, 4] }) 
  .then(result => console.log(result))
  .catch(error => console.error(error))

Form

For sending a form you should use .form(form) method

BackendlessRequest.post('http://foo.bar/')
  .form(form)
  .then(result => console.log(result))
  .catch(error => console.error(error))

The method accepts a plain object, an instance of Request.FormData and a WHATWG FormData - the global one of Node 18+ and the browser one:

const form = new FormData()                      // the global FormData
form.append('title', 'a report')
form.append('file', new Blob([bytes]), 'report.pdf')

await BackendlessRequest.post('http://foo.bar/').form(form)

A Blob and a File are supported as a form value as well, in Node js they are streamed and their size is used for the content-length header, so a large file is not kept in memory twice:

const bytes = await BackendlessRequest.get('http://foo.bar/report.pdf').toBuffer()

await BackendlessRequest.post('http://vendor.bar/upload')
  .form({
    // a Buffer, a stream, a Blob, a File and a primitive value are all accepted
    file : new Blob([bytes], { type: 'application/pdf' }),

    // the { value, options } form still works and its options win
    other: { value: bytes, options: { filename: 'report.pdf', contentType: 'application/pdf' } },
  })

A nameless Blob is sent as filename="blob", the same as a browser does. A value which can not be sent as a form part is reported with an error naming the field, instead of an Illegal invocation/source.on is not a function thrown from inside the form streaming later on.

In Node js Request.FormData is the form-data package, and it accepts only a Buffer, a stream or a primitive value. Appending a Blob directly to such an instance still throws source.on is not a function at append time - that happens inside the package, before this library sees the form. Pass the Blob through .form(), or use the global FormData, and it will be converted for you.

ContentType Header

To manually set up the Content-Type header, you can use the .type(contentTypeHeader) method or set it via .set('Content-Type', value) method. If you pass an object as a request body the Content-Type header will be automatically specified as application/json

BackendlessRequest.get('https://foo.bar/')
  .set('x-header-key', 'x-header-value')
  .set({ 'y-header-key': 'y-header-value', 'z-header-key': 'z-header-value' })
  .then(result => console.log(result))
  .catch(error => console.error(error))

Downloading Binary Data

Use .toBuffer() to download raw bytes - a PDF, an image, a video - and forward them somewhere else. The method is terminal, it sends the request and always resolves the body as bytes: a Buffer in Node js and a Uint8Array in a browser. Since a Buffer is a Uint8Array, result instanceof Uint8Array is a check which holds in both environments.

const bytes = await BackendlessRequest.get('https://foo.bar/report.pdf').toBuffer()

form.append('file', bytes, 'report.pdf')

The guarantee is unconditional, unlike .setEncoding(null):

  • the body is never passed to JSON.parse, so a downloaded file is returned byte for byte even when its content happens to be valid JSON ({"a":1}, 42, null, "abc");
  • a response with no body, a 204 or a Content-Length: 0, resolves to an empty buffer, never to '';
  • there is no need to call .setEncoding(null) as well, .toBuffer() implies a raw transfer and overrides an encoding which was set before it.

An unsuccessful response is rejected as usual, and its body is still parsed when it is JSON, so an error message coming from the server stays readable:

try {
  const bytes = await BackendlessRequest.get('https://foo.bar/report.pdf').toBuffer()
} catch (error) {
  console.error(error.status)       // 404
  console.error(error.body.message) // the parsed error body of the server
}

.unwrapBody(false) works together with .toBuffer(), in that case the whole response is resolved and its body is the bytes.

.setEncoding(null) keeps its current behaviour for backward compatibility, including passing the body to JSON.parse. Prefer .toBuffer() for any binary download.

Client Certificate (mutual TLS)

Some APIs, most of them in regulated banking, require the client to present a TLS certificate of its own before they will answer at all. Use the .cert(tlsOptions) method to attach one.

BackendlessRequest.post('https://api.vendor.com/some-path')
  .cert({
    cert      : clientCertPem,   // PEM encoded client certificate (or chain)
    key       : clientKeyPem,    // PEM encoded private key
    passphrase: keyPassphrase,   // optional, for an encrypted private key
    ca        : caBundlePem      // optional, a custom CA bundle to verify the server with
  })
  .set({ 'Content-Type': 'application/json' })
  .send(body)
  .then(result => console.log(result))
  .catch(error => console.error(error))

Every option accepts a String, a Buffer or an array of them, exactly as the Node TLS options do. Options other than the four above are ignored, so a connection can not be weakened by accident.

The method can be called several times and the options are merged, which lets the certificate and the key come from different places:

BackendlessRequest.get('https://api.vendor.com/accounts')
  .cert({ cert: clientCertPem, key: clientKeyPem })
  .cert({ ca: caBundlePem })

A few things worth knowing:

  • The certificate must be attached to the token request too. Servers of this kind usually demand the certificate before authentication, so their OAuth2 token endpoint is unreachable without it as well.
  • It works in Node.js only. In a browser XMLHttpRequest gives no control over the client certificate, the browser picks one from the keystore itself, so .cert() there does nothing.
  • A client certificate requires an https:// URL. Sending it over http:// would silently drop it and put the request on the wire in plain text, so the request fails instead.
  • ca replaces the default trust store for that request, the same way curl --cacert does. Pass the full chain that is needed to verify the server.
  • The private key is credential material. Store it the way you store a password, never inline it into a URL. The library keeps it out of BackendlessRequest.verbose output and off the enumerable properties of the request, so it does not end up in a log through console.log(request) or JSON.stringify(request).

TLS errors

A failed handshake would otherwise surface as an opaque socket error, so recognized failures are raised as a TLSError with a message that says what went wrong. error.code keeps the original Node/OpenSSL code and error.cause the original error.

The server requires a client certificate and none was supplied. (ERR_SSL_TLSV13_ALERT_CERTIFICATE_REQUIRED)
The server rejected the client certificate because it has expired. (EPROTO)
The private key could not be decrypted, the passphrase is missing or incorrect. (ERR_OSSL_BAD_DECRYPT)
The client certificate or the private key is not valid PEM. (ERR_OSSL_PEM_NO_START_LINE)
The server certificate has expired. (CERT_HAS_EXPIRED)
The server certificate could not be verified, a CA bundle may be required. (UNABLE_TO_VERIFY_LEAF_SIGNATURE)

When a server just drops the connection instead of sending a TLS alert, which is what a TLS 1.3 server typically does when it does not accept the certificate, the error says so:

The connection was closed during the TLS handshake, the client certificate was most likely missing,
rejected or expired. (ECONNRESET)

Errors which have nothing to do with TLS are left untouched.

Request Events

A request instance might fire events to notify about changing request state:

for subscribing use method .on(<eventName>, callback)

BackendlessRequest.post('https://foo.bar/some-path')
  .on('request', req => req.set('my-x-header-key', 'my-x-header-value')) 
  .on('response', result => console.log('result', result)) 
  .on('error', error => console.log('error', error))
  .on('done', (error, result) => console.log('done', { error, result })) 
  .send({ str: 'some-string', num: 123, bool: true, list: [1, 2, 3, 4] })
  .then(result => console.log(result))
  .catch(error => console.error(error))
  • request - it will be fired before sending a request to the server

  • response - it will be fired when a request is successfully completed

  • error - it will be fired when a request is failed

  • done - it will be fired when a request is done, it's a shortcut for response and error

Own XMLHttpRequest

You can use your own XMLHttpRequest, just replace it in BackendlessRequest namespace.

See Example


class MySupperXMLHttpRequest {
  
  open(){
    
  }
  
  ...
  
  send(){
    
  }
}

BackendlessRequest.XMLHttpRequest = MySupperXMLHttpRequest

Logging

If you want to log all the requests just set true for verbose

BackendlessRequest.verbose = true