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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@root/request

v1.9.2

Published

A lightweight, zero-dependency drop-in replacement for request

Downloads

90,314

Readme

@root/request | a Root project

Minimalist HTTP client

A lightweight alternative to (and 80/20 drop-in replacement for) request.

Has the 20% of features that 80%+ of people need, in about 500 LoC.

Written from scratch, with zero-dependencies.

Super simple to use

@root/request is designed to be a drop-in replacement for request. It also supports Promises and async/await by default, enhanced stream support, and a few other things as mentioned below.

npm install --save @root/request

# or npm install git+ssh://[email protected]/request.js
var request = require('@root/request');
request('http://www.google.com', function (error, response, body) {
    console.log('error:', error); // Print the error if one occurred
    console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
    console.log('body:', body); // Print the HTML for the Google homepage.
});

Using Promises

var request = require('@root/request');

request('http://www.google.com')
    .then(function (response) {
        console.log('statusCode:', response.statusCode); // Print the response status code if a response was received
        console.log('body:', response.body); // Print the HTML for the Google homepage.
    })
    .catch(function (error) {
        console.log('error:', error); // Print the error if one occurred
    });

Streaming

In order to keep this library lightweight, performant, and keep the code easy to read, the streaming behavior is slightly different from that of request.js.

-var request = require('request');
+var request = require('@root/request');

-var stream = request({ url, headers });
+var stream = await request({ url, headers });

 let attachment = await new MailgunAPI.Attachment({
   data: stream
 })

Example:

var request = require('@root/request');

var resp = await request({
    url: 'http://www.google.com',
    stream: true // true | 'filename.ext' | stream.Writable
});

// 'resp' itself is a ReadableStream
resp.on('data', function () {
    // got some data
});

resp.on('end', function () {
    // the data has ended
});

// 'resp.stream' is a Promise that is resolved when the read stream is destroyed
await resp.stream; // returns `undefined`
console.log('Done');

The difference is that we don't add an extra layer of stream abstraction. You must use the response from await, a Promise, or the callback.

You can also give a file path:

request({
    url: 'http://www.google.com',
    stream: '/tmp/google-index.html'
});

Which is equivalent to passing a write stream for the file:

request({
    url: 'http://www.google.com',
    stream: fs.createWriteStream('/tmp/google-index.html')
});

Also, await resp.stream.body() can be used to get back the full body (the same as if you didn't use the stream option:

let resp = await request({
    url: 'http://www.google.com',
    stream: true
});
if (!resp.ok) {
    await resp.stream.body();
    console.error(resp.body);
}

Table of contents

Extra Features

The following are features that the original request did not have, but have been added for convenience in @root/request.

  • Support for async/await & Promises (as explained above)
  • request({ userAgent: 'my-api/1.1' }) (for building API clients)
  • resp.ok (just like fetch)
  • resp.stream (see above)

See EXTRA.md

Forms

@root/request supports application/x-www-form-urlencoded and multipart/form-data form uploads.

application/x-www-form-urlencoded (URL-Encoded Forms)

URL-encoded forms are simple.

request.post('http://service.com/upload', { form: { key: 'value' } });
// or
request.post(
    { url: 'http://service.com/upload', form: { key: 'value' } },
    function (err, httpResponse, body) {
        /* ... */
    }
);

multipart/form-data (Multipart Form Uploads)

For multipart/form-data we use the form-data library by @felixge. For the most cases, you can pass your upload form data via the formData option.

To use form-data, you must install it separately:

npm install --save [email protected]
var formData = {
    // Pass a simple key-value pair
    my_field: 'my_value',
    // Pass data via Buffers
    my_buffer: Buffer.from([1, 2, 3]),
    // Pass data via Streams
    my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
    // Pass multiple values /w an Array
    attachments: [
        fs.createReadStream(__dirname + '/attachment1.jpg'),
        fs.createReadStream(__dirname + '/attachment2.jpg')
    ],
    // Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
    // Use case: for some types of streams, you'll need to provide "file"-related information manually.
    // See the `form-data` README for more information about options: https://github.com/form-data/form-data
    custom_file: {
        value: fs.createReadStream('/dev/urandom'),
        options: {
            filename: 'topsecret.jpg',
            contentType: 'image/jpeg'
        }
    }
};
request.post(
    { url: 'http://service.com/upload', formData: formData },
    function optionalCallback(err, httpResponse, body) {
        if (err) {
            return console.error('upload failed:', err);
        }
        console.log('Upload successful!  Server responded with:', body);
    }
);

See the form-data README for more information & examples.


HTTP Authentication

request.get('http://some.server.com/', {
    auth: {
        user: 'username',
        pass: 'password',
        sendImmediately: false
    }
});
// or
request.get('http://some.server.com/', {
    auth: {
        bearer: 'bearerToken'
    }
});

If passed as an option, auth should be a hash containing values:

  • user || username
  • pass || password
  • bearer (optional)

Note that you can also specify basic authentication using the URL itself, as detailed in RFC 1738. Simply pass the user:password before the host with an @ sign:

var username = 'username',
    password = 'password',
    url = 'http://' + username + ':' + password + '@some.server.com';

request({ url: url }, function (error, response, body) {
    // Do more stuff with 'body' here
});

Bearer authentication is supported, and is activated when the bearer value is available. The value may be either a String or a Function returning a String. Using a function to supply the bearer token is particularly useful if used in conjunction with defaults to allow a single function to supply the last known token at the time of sending a request, or to compute one on the fly.

back to top


Custom HTTP Headers

HTTP Headers, such as User-Agent, can be set in the options object. In the example below, we call the github API to find out the number of stars and forks for the request repository. This requires a custom User-Agent header as well as https.

var request = require('request');

var options = {
    url: 'https://api.github.com/repos/request/request',
    headers: {
        'User-Agent': 'request'
    }
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        var info = JSON.parse(body);
        console.log(info.stargazers_count + ' Stars');
        console.log(info.forks_count + ' Forks');
    }
}

request(options, callback);

back to top


UNIX Domain Sockets

@root/request supports making requests to UNIX Domain Sockets. To make one, use the following URL scheme:

/* Pattern */ 'http://unix:SOCKET:PATH';
/* Example */ request.get(
    'http://unix:/absolute/path/to/unix.socket:/request/path'
);

Note: The SOCKET path is assumed to be absolute to the root of the host file system.

back to top


request(options, callback)

The first argument can be either a url or an options object. The only required option is uri; all others are optional.

  • uri || url - fully qualified uri or a parsed url object from url.parse()
  • method - http method (default: "GET")
  • headers - http headers (default: {})

  • body - entity body for PATCH, POST and PUT requests. Must be a Buffer, String or ReadStream. If json is true, then body must be a JSON-serializable object.
  • json - sets body to JSON representation of value and adds Content-type: application/json header. Additionally, parses the response body as JSON.

  • followRedirect - follow HTTP 3xx responses as redirects (default: true). This property can also be implemented as function which gets response object as a single argument and should return true if redirects should continue or false otherwise.
  • followAllRedirects - follow non-GET HTTP 3xx responses as redirects (default: false)
  • followOriginalHttpMethod - by default we redirect to HTTP method GET. you can enable this property to redirect to the original HTTP method (default: false)
  • maxRedirects - the maximum number of redirects to follow (default: 10)
  • removeRefererHeader - removes the referer header when a redirect happens (default: false). Note: if true, referer header set in the initial request is preserved during redirect chain.

  • encoding - encoding to be used on setEncoding of response data. If null, the body is returned as a Buffer. Anything else (including the default value of undefined) will be passed as the encoding parameter to toString() (meaning this is effectively utf8 by default). (Note: if you expect binary data, you should set encoding: null.)

Convenience methods

There are also shorthand methods for different HTTP METHODs and some other conveniences.

request.defaults(options)

This method returns a wrapper around the normal request API that defaults to whatever options you pass to it.

Note: request.defaults() does not modify the global request API; instead, it returns a wrapper that has your default settings applied to it.

Note: You can call .defaults() on the wrapper that is returned from request.defaults to add/override defaults that were previously defaulted.

For example:

//requests using baseRequest() will set the 'x-token' header
var baseRequest = request.defaults({
    headers: { 'x-token': 'my-token' }
});

//requests using specialRequest() will include the 'x-token' header set in
//baseRequest and will also include the 'special' header
var specialRequest = baseRequest.defaults({
    headers: { special: 'special value' }
});

request.METHOD()

These HTTP method convenience functions act just like request() but with a default method already set for you:

  • request.get(): Defaults to method: "GET".
  • request.post(): Defaults to method: "POST".
  • request.put(): Defaults to method: "PUT".
  • request.patch(): Defaults to method: "PATCH".
  • request.del() / request.delete(): Defaults to method: "DELETE".
  • request.head(): Defaults to method: "HEAD".
  • request.options(): Defaults to method: "OPTIONS".

Debugging

There are at least two ways to debug the operation of request:

  1. Launch the node process like NODE_DEBUG=@root/request node script.js (lib,request,otherlib works too).

  2. Set require('@root/request').debug = true at any time (this does the same thing as #1).

back to top