Promises/A+, request-powered, boom-enabled, JSON-first HTTP API client with automatic retry
Install with npm:
npm install habrok --saveconst Habrok = require('habrok');
const habrok = new Habrok();
habrok.request({
method: 'GET',
uri: 'https://api.github.com/repositories'
})
.then(console.log);{
"statusCode": 200,
"headers": {
"content-length": "4477",
"content-type": "application/json; charset=utf-8",
"etag": "6ffc6a0dbbe2613e4d8b3f7444e5c604",
...
},
"body": [
{
"id": 1296269,
"private": false,
"owner": {
"id": 1,
"login": "octocat",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
...
},
"name": "hello-World",
"full_name": "octocat/hello-world",
"description": "Octocat's first repo!",
"url": "https://api.github.com/repos/octocat/hello-world",
...
},
...
]
}Habrok([configuration])None
configuration:Objectwith one or more of the below properties:
| Property | Type | Description | Default |
|---|---|---|---|
disableAutomaticJson |
Boolean |
Disable JSON headers and request/response bodies | false |
disableCustomHeaders |
Boolean |
Disable request headers added by Habrok | false |
disableRetryEconnreset |
Boolean |
Disable retry for connection reset errors | false |
retries |
Number |
Number of times to retry a failed request | 5 |
retryMinDelay |
Number |
Minimum milliseconds to wait before retrying a request | 100 |
retryMaxDelay |
Number |
Maximum milliseconds to wait before retrying a request | None |
retryCodes |
Array<Number> |
HTTP status codes that trigger a retry | [429, 502, 503, 504] |
By default, each request includes the following headers (which can be prevented with disableCustomHeaders):
User-Agent:habrok/[MAJOR.MINOR.PATCH], versioned according topackage.json(e.g.habrok/1.0.0)X-Node-Platform: Directly fromprocess.platform(e.g.linux)X-Node-Version: Derived fromprocess.version(e.g.6.11.1)
The retry logic follows exponential backoff, summarized as:
MINIMUM(retryMaxDelay, retryMinDelay * (attempt ** 2))
With the default configuration, a failing request observes a delay sequence of 100, 400, 900, and 1600 milliseconds before rejecting with an error.
A Habrok HTTP API Client instance.
Construct a default client:
const Habrok = require('habrok');
const habrok = new Habrok();Construct a client with a minimum retry delay of 250 milliseconds:
const Habrok = require('habrok');
const habrok = new Habrok({ retryMinDelay: 250 });Construct a client that does not send Habrok-generated headers:
const Habrok = require('habrok');
const habrok = new Habrok({ disableCustomHeaders: true });habrok.request(req[, options])req:Object, a request-compatible object
options:Objectwith one or more of the below properties:
| Property | Type | Description | Default |
|---|---|---|---|
attempt |
Number |
Integer indicating current request sequence number | None |
onRetry |
Function |
A function executed whenever Habrok retries a request. As an argument, it will pass in an object with same properties returned by a habrok.request. |
None |
debugRequest |
Function |
A function called after making a successful request or after the maximum number of attempts is met. As an argument, it will pass in an object with the property attempt, the number of attempts made. |
None |
Generally, attempt is not needed. The internal retry engine will pass the current attempt count into the next request. Override only as necessary – e.g. in cases where the retry logic should be bypassed.
Parameters
| Parameter | Type | Description |
|---|---|---|
| statusCode | Number |
The HTTP status code of the request that necessitated this retry. |
| error | Object |
A boom-js error. |
Returns None
Parameters
| Parameter | Type | Description |
|---|---|---|
| debugInfo | Object |
An object containing information about the series of requests. |
debugInfo
| Key | Type | Description |
|---|---|---|
attempts |
Number |
The total number of http requests made for a habrok.request. If retries is set to 0, and this will always be 1. |
Returns None
A Promise that resolves to an Object with the following properties:
statusCode:Number, the HTTP status code provided in the responseheaders:Object, HTTP headers (lower-cased) and their values provided in the responsebody:Any, the JSON-parsed response body (or the raw body ifdisableAutomaticJsonwas set)
The Promise is rejected with a Boom-wrapped error if an HTTP error occurs. The Promise is rejected with a generic Error if an error is returned by the underlying request library (usually from http.ClientRequest).
Send a GET request:
habrok.request({
method: 'GET',
uri: 'https://api.viki.ng/longships'
})Send a POST request:
habrok.request({
method: 'POST',
uri: 'https://api.viki.ng/longships',
json: {
name: 'Oseberg'
}
})The debug module is used for runtime logging. Omit the DEBUG environment variable to squelch all logging. Set DEBUG to the desired level (e.g. DEBUG=habrok) to restrict logging to a desired service. Or, use DEBUG=* to get all debug output from everywhere, including dependencies.
DEBUG=@agilemd/habrok* node indexTo run the unit tests:
npm testThis project maintains ~100% coverage of statements, branches, and functions. To determine unit test coverage:
npm run coveragePRs are welcome! PRs must pass unit tests and linting prior to merge. PRs must not reduce unit coverage. For bugs, please include a failing test which passes when your PR is applied. To enable a git hook that runs npm test prior to pushing, cd into your repo and run:
touch .git/hooks/pre-push
chmod +x .git/hooks/pre-push
echo "npm test" > .git/hooks/pre-pushThis project follows semantic versioning. See the changelog for release information.
- This module is licensed under the ISC License
- The underlying
boommodule is licensed under the BSD 3-Clause License - The underlying
debugmodule is licensed under the MIT License - The underlying
hasmodule is licensed under the MIT License - The underlying
requestmodule is licensed under the Apache 2.0
From Grímnismál, Stanza 44:
The best of trees must Yggdrasil be, Skithblathnir best of boats; Of all the gods is Odin the greatest, And Sleipnir the best of steeds; Bifrost of bridges, Bragi of skalds, Habrok of hawks, and Garm of hounds.
Habrok, data-in-flight at its best.