# Common Interface for HTTP Clients
A module conforming to this specification is:
1. A function that expects the common options object outlined in this specification
2. A function that initiates the actual HTTP request while consuming the options outlined in this specification
```js
module.exports = (options) => {
// do something with options
// and make the actual HTTP request
}
```
Given the above module definition, a client application can use it like this:
```js
var request = require('my-http-client')
// make request
request({
// any common option defined in this specification
})
```
## HTTP Client Wrappers
```js
var http = require('http')
module.exports = (options) => {
// do something with the common interface options
var resultOptions = {}
// implement various HTTP features
return http.request(resultOptions)
}
```
---
```js
var request = require('request')
module.exports = (options) => {
// do something with the common interface options
var resultOptions = {}
// implement various HTTP features
return request(resultOptions)
}
```
---
```js
// use the native fetch API in the browser
module.exports = (options) => {
// do something with the common interface options
var resultOptions = {}
// implement various HTTP features
return fetch(new Request(url, resultOptions))
}
```
Either way the client application should be able to make requests in a consistent way:
```js
var request = require('my-http-client')
// make request
request({
// any common option defined in this specification
})
```
## Optional Dependencies
A module conforming to this specification while having optional dependencies may look like this:
```js
module.exports = (deps) => (options) => {
var resultOptions = {}
if (options.oauth) {
resultOptions.oauth = deps.oauth(options.oauth)
}
return request(resultOptions)
}
```
Given the above module definition, a client application can use it like this:
```js
var request = require('my-http-client')({
oauth: require('my-oauth-implementation')
})
// make request
request({
// any common option defined in this specification
})
```
## Bundled Dependencies
A module conforming to this specification while having *hardcoded* dependencies may look like this:
```js
module.exports = require('my-http-client')({
oauth: require('my-oauth-implementation')
})
```
Given the above module definition, a client application can use it like this:
```js
var request = require('my-http-client')
// make request
request({
// any common option defined in this specification
})
```
## Basic API
A module using the common [@request/api][request-api] may look like this:
```js
var request = require('my-http-client')
var api = require('@request/api')
module.exports = api({
type: 'basic',
request: request
})
```
Given the above module definition, a client application can use it like this:
```js
var request = require('my-http-client')
// make request
request('url', {options}, (err, res, body) => {})
// or
request.[HTTP_VERB]('url', {options}, (err, res, bdoy) => {})
// + any combination of the above arguments
```
## Chain API
A module using the common [@request/api][request-api] may look like this:
```js
var request = require('my-http-client')
var api = require('@request/api')
module.exports = api({
type: 'chain',
config: {
method: {
get: [],
// ...
},
option: {
qs: [],
// ...
},
custom: {
submit: [],
// ...
}
},
define: {
submit: function (callback) {
if (callback) {
this._options.callback = callback
}
return request(this._options)
}
}
})
```
Given the above module definition, a client application can use it like this:
```js
var request = require('my-http-client')
// make request
request
.get('url')
.qs({a: 1})
.submit((err, res, body) => {})
```
## Promises
A module utilizing Promises may look like this:
```js
module.exports = (deps) => (options) => {
var request = deps.request
if (deps.promise) {
var Promise = deps.promise
var promise = new Promise((resolve, reject) => {
options.callback = (err, res, body) => {
if (err) {
reject(err)
}
else {
resolve([res, body])
}
}
})
request(options)
return promise
}
else {
return request(options)
}
}
```
Given the above module definition, a client application can use it like this:
```js
var request = require('my-http-client')({
request: require('request'),
promise: Promise
})
// or
var request = require('my-http-client')({
request: require('request'),
promise: require('bluebird')
})
// make request
request({options})
.catch((err) => {})
.then((result) => {})
```
Promises can be combined with the [@request/api][request-api].
# Interface
option | type
:--- | :---
method | `String`
**URL** |
url/uri | `String`, `Object`
qs | `Object`, `String`
**Body** |
form | `Object`, `String`
json | `Object`, `String`
body | `Stream`, `Buffer`, `Array`, `String`
multipart | `Object`, `Array`
**Authentication** |
auth | `Object`
| basic, oauth, hawk, httpSignature, aws
**Modifiers** |
gzip | `Boolean`, `String`
encoding | `Boolean`, `String`
stringify | `Object`
parse | `Object`
**Proxy** |
proxy | `String`, `Object`
tunnel | `Boolean`
**Misc** |
headers | `Object`
cookie | `Boolean`, `Object`
length | `Boolean`
callback | `Function`
redirect | `Boolean`, `Object`
timeout | `Number`
har | `Object`
end | `Boolean`
---
## Method
### method `String`
---
## URL
### url/uri `String` | `Object`
- `String`
- `url.Url`
### qs `Object` | `String`
- `Object`
- `String`
---
## Body
### form `Object` | `String`
- `Object`
- `String` pass URL encoded string if you want it to be RFC3986 encoded prior sending
### json `Object` | `String`
- `Object`
- `String`
### body `String` | `Buffer` | `Array` | `Stream`
- `Stream`
- `Buffer`
- `String`
- `Array`
### multipart `Object` | `Array`
- `Object` for `multipart/form-data`
- `Array` for any other `multipart/[TYPE]`, defaults to `multipart/related`
Each item's body can be either: `Stream`, `Request`, `Buffer` or `String`.
- `_multipart`
- `data` - the above
Additionally you can set `preambleCRLF` and/or `postambleCRLF` to `true`.
---
## Authentication
### auth `Object`
- `basic`
- `{user: '', pass: '', sendImmediately: false, digest: true}`
- Sets the `Authorization: Basic ...` header.
- The `sendImmediately` option default to `true` if omitted.
- The `sendImmediately: false` options requires the [redirect option][redirect-option] to be enabled.
- Digest authentication requires the [@request/digest][request-digest] module.
- `bearer`
- `{token: '', sendImmediately: false}`
- Alternatively the `Authorization: Bearer ...` header can be set if using the `bearer` option.
- The rules for the `sendImmediately` option from above applies here.
- `oauth`
- `hawk`
- `httpSignature`
- `aws`
---
## Modifiers
### gzip `Boolean` | `String`
- `true`
- Pipes the response body to [zlib][zlib] Inflate or Gunzip stream based on the compression method specified in the `content-encoding` response header.
- `'gzip'` | `'deflate'`
- Explicitly specify decompression method to use.
### encoding `Boolean` | `String`
- `true`
- Pipes the response body to [iconv-lite][iconv-lite] stream, defaults to `utf8`.
- `'ISO-8859-1'` | `'win1251'` | ...
- Specific encoding to use.
- `'binary'`
- Set `encoding` to `'binary'` when expecting binary response.
### parse `Object`
- `{json: true}`
- sets the `accept: application/json` header for the request
- parses `JSON` or `JSONP` response bodies *(only if the server responds with the approprite headers)*
- `{json: function () {}}`
- same as above but additionally passes a user defined reviver function to the `JSON.parse` method
- `{qs: {sep:';', eq:':'}}`
- [qs.parse()][qs] options to use
- `{querystring: {sep:';', eq:':', options: {}}}` use the [querystring][querystring] module instead
- [querystring.parse()][querystring] options to use
### stringify `Object`
- `{qs: {sep:';', eq:':'}}`
- [qs.stringify()][qs] options to use
- `{querystring: {sep:';', eq:':', options: {}}}` use the [querystring][querystring] module instead
- [querystring.stringify()][querystring] options to use
---
## Proxy
### proxy `String` | `Object`
```js
{
proxy: 'http://localhost:6767'
//
proxy: url.parse('http://localhost:6767')
//
proxy: {
url: 'http://localhost:6767',
headers: {
allow: ['header-name'],
exclusive: ['header-name']
}
}
}
```
### tunnel `Boolean`
- `true`
---
## Misc
### headers `Object`
### cookie `Boolean` | `Object`
- `true`
- `new require('tough-cookie).CookieJar(store, options)`
### length `Boolean`
- `true` defaults to `false` if omitted
### callback `Function`
- `function (err, res, body) {}` buffers the response body
- by default the response buffer is decoded into string using `utf8`.
Set the `encoding` property to `binary` if you expect binary data, or any other specific encoding.
### redirect `Boolean` | `Object`
- `true`
- follow redirects for `GET`, `HEAD`, `OPTIONS` and `TRACE` requests
- `Object`
- *all* - follow all redirects
- *max* - maximum redirects allowed
- *removeReferer* - remove the `referer` header on redirect
- *allow* - `function (res)` user defined function to check if the redirect should be allowed
### timeout `Number`
- integer indicating the number of milliseconds to wait for a server to send response headers (and start the response body) before aborting the request. Note that if the underlying TCP connection cannot be established, the OS-wide TCP connection timeout will overrule the timeout option
### har `Object`
### end `Boolean`
- `true`
- tries to automatically end the request on `nextTick`
---
[request-api]: https://github.com/request/api
[qs]: https://www.npmjs.com/package/qs
[querystring]: https://nodejs.org/dist/latest-v6.x/docs/api/querystring.html
[request]: https://github.com/request/request
[request-contributors]: https://github.com/request/request/graphs/contributors
[zlib]: https://iojs.org/api/zlib.html
[node-http-request]: https://nodejs.org/api/http.html#http_http_request_options_callback
[tough-cookie]: https://github.com/SalesforceEng/tough-cookie
[iconv-lite]: https://www.npmjs.com/package/iconv-lite
[hawk]: https://github.com/hueniverse/hawk
[aws-sign2]: https://github.com/request/aws-sign
[http-signature]: https://github.com/joyent/node-http-signature
[tunnel-agent]: https://github.com/mikeal/tunnel-agent
[request-core]: https://github.com/request/core
[request-headers]: https://github.com/request/headers
[request-digest]: https://github.com/request/digest
[request-oauth]: https://github.com/request/oauth
[request-multipart]: https://github.com/request/multipart
[request-log]: https://github.com/request/log
[redirect-option]: #redirect