Package Exports
- resilient
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (resilient) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
resilient.js

A browser and node.js fault tolerant, balanced, configurable and full featured HTTP client for distributed and reactive systems
For more information about Resilient, see the project site
Note: resilient.js is still beta
Features
- Fault tolerant, transparent server fallback
- Client-side based balancer using a simple best availability algorithm
- Smart balancer logic based on server stats (latency, errors, requests...)
- Configurable balancer policy by weight
- Highly configurable (timeout, retry times, cache, wait delay fallback...)
- Built-in support for request traffic listeners and interceptors
- Built-in support for servers caching to improve reliability for fallback
- Parallel servers discovering for a faster availability
- Allows to define an external HTTP client to use as proxy for requests traffic
- Support for round robin scheduling algorithm (experimental)
- Cross engine (node.js and browsers ES5 compliant)
- Servers discovering based on the resilient high-level protocol
- Server-side dynamic client configuration support (experimental)
- Full HTTP features support (it uses request and lil-http)
- Lightweight library (just 6KB gzipped)
Installation
Node.js
npm install resilientBrowser
Via Bower
bower install resilientVia Component
component install resilient-http/resilient.jsOr loading the script remotely
<script src="//cdn.rawgit.com/resilient-http/resilient.js/0.1.2/resilient.js"></script>Environments
It runs properly in any ES5 compliant engine
- Node.js
- Chrome >= 5
- Firefox >= 3
- Safari >= 5
- Opera >= 10
- IE >= 9
How it works?
An algorithm diagram worth more than words
Basic usage
If require is available, you must use it to fetch the module.
Otherwise it will be available as global exposed as resilient
var Resilient = require('resilient')Static servers
Define your server pool
var servers = [
'http://api1.server.com',
'http://api2.server.com',
'http://api3.server.com'
]Create a new client and set the servers
var client = Resilient({ service: { basePath: '/api/1.0' }})
client.setServers(servers)Perform the request (the best available server will be use)
client.get('/users', function (err, res) {
if (res.status === 200) {
console.log('Success:', res.data)
}
})Dynamic servers discovering
Define the discovery servers pool
var servers = [
'http://discover1.server.com',
'http://discover2.server.com',
'http://discover3.server.com'
]Create a new client and set the discovering servers
var client = Resilient({ service: { basePath: '/api/1.0' }})
client.discoveryServers(servers)Perform a request (and that's all)
client.get('/users', function (err, res) {
if (res.status === 200) {
console.log('Success:', res.data)
}
})API
resilient([ options ])
Creates a new resilient client with a custom config
Options
The options object has three different blocks and levels of configuration
Service
There are specific config options for the servers of the client service. Resilient is a resource-oriented HTTP client, which could be ideal for RESTful Web services
- servers
array- A list of valid URIs of servers to reach for the given service. Defaultnull. It's recommended you use discovery servers instead - retry
number- Number of times to retry if all requests failed. Default0 - retryWait
number- Number of milisenconds to wait before retry. Default to1000 - discoverBeforeRetry
boolean- Force to refresh service servers list from asking for discovery servers on each retry attempt. You must define the discovery servers in order to use this feature. Defaulttrue
Specific shared configuration options for the HTTP client for final service requests
- path
string- Server request path as part of the final URL - basePath
string- Server resource base path to share between all requests - method
string- Request HTTP method. Default toGET - data
mixed- Payload data to send as body request - headers
object- Map of strings representing HTTP headers to send to the server - timeout
number- Request maximum timeout in miliseconds before to abort it. Default to 10 seconds - auth
object- Authentication credentials to the server. Object must have theuserandpasswordproperties
Browser specific options
- async
boolean- Set tofalseif the request must be performed as synchronous operation (not recommended, browser only) - withCredentials
boolean- Whether to set the withCredentials flag on the XHR object. See [MDN][withcredentials] for more information - responseType
string- Define how to handle the response data. Allowed values are:text,arraybuffer,blobordocument
Node.js specific options
See all HTTP options supported for node.js here
Balancer
- enable
boolean- Enable/disable the smart client balancer. Defaulttrue - roundRobin
boolean- Enable RobinRobin scheudle algorithm (experimental) - roundRobinSize
number- Round robin round size. Useful to increase requests distribution across different servers. Default to3servers - weight
object- Balacer point percentage weight for server scoring policy:- success
number- Percentage weight for success request. Default to15 - error
number- Percentage weight for failed request. Default to50 - latency
number- Percentage weight for request average latency. Default to35
- success
Discovery
Specific configuration for discovery servers requests, behavior and logic
- servers
array- A list of valid URIs of endpoints to use as discovery servers - cache
boolean- Enable/disable discovery servers cache in case of global fallback. Defaulttrue - cacheExpiration
number- Maximum cache time to live. Default to10minutes - retry
number- Number of times to retry if all requests failed. Default0 - retryWait
number- Number of milisenconds to wait before retry. Default to1000 - parallel
boolean- Discover servers in parallel. Improve service availability and decrement delay times. Recommended. Defaulttrue
Specific shared configuration options for the HTTP client in discovering processes
- path
string- Server request path as part of the final URL - basePath
string- Server resource base path to share between all requests - timeout
number- Server discovery network timeout in miliseconds. Default2seconds - auth
object- Authentication credentials required for the discovery server. Object must have theuserandpasswordproperties - headers
object- Map of strings representing HTTP headers to send to the discovery server - method
string- Request HTTP method. Default toGET - data
mixed- Optional data to send as payload to discovery servers. Defaultnull
Request callback arguments
- error Error|ResilientError - Response error, if happends. Otherwise
null - response Object|http.IncomingMessage - Response object
Response
Browser
- data
mixed- Body response. If the MIME type isJSON-compatible, it will be transparently parsed - status
number- HTTP response status code - headers
object- Response headers - xhr
object- Original XHR instance - error
mixed- Error info, usually anErrorinstance (in case that an error happens)
Node.js
Error
It will be an Error instance with the following members
- message
string- Human readable error message - status
number- Internal error code or HTTP status - code
number- Optional error code (node.js only) - stack
string- Optional stack error trace - request
object- Original response object (node.js only). Optional - error
Error- Original throwed error object (node.js only). Optional - xhr ``
Built-in error codes
- 1000 - All requests failed. No servers available
- 1001 - Cannot update discovery servers. Empty or invalid response body
- 1002 - Missing discovery servers. Cannot resolve the server
- 1003 - Cannot resolve servers. Missing data
- 1004 - Discovery server response is invalid or empty
- 1005 - Missing discovery servers during retry process
- 1006 - Internal state error (usually caused by an unexpected exception)
Events
Resilient client has a built-in support for internal states event dispacher and notifier to the public interface
This could be useful really useful while using an interceptor pattern in order to detect states and data changes. You can intercept and change any request configuration and response subscribing to the pre/post hooks. Note that mutation is required, you should modify it by reference and do not lose it
discovery.refresh
Arguments: servers<Array>, resilient<Resilient>
Fired every time that servers are updated from discovery servers
discovery.cache
Arguments: servers<Array>, resilient<Resilient>
Fired every time that servers cache is updated
request.start
Arguments: options<Object>, resilient<Resilient>
Fired as before a request is created
You can intercept and modify the request options on the fly, but you must mutate it and do not lose its reference
request.finish
Arguments: error<Error>, response<Object|http.IncomingMessage>, resilient<Resilient>
Fired as after a request was completed
You can intercept and modify the error/response on the fly, but you must mutate it and do not lose its reference
resilient#send(path, options, callback)
Performs a custom request with the given options. It's recommended using as generic interface to make multi verb requests
resilient#get(path, options, callback)
Creates a GET request with optional custom options
resilient#post(path, options, callback)
Creates a POST request with optional custom options
resilient#put(path, options, callback)
Creates a PUT request with optional custom options
resilient#del(path, options, callback)
Creates a DELETE request with optional custom options
resilient#patch(path, options, callback)
Creates a PATCH request with optional custom options
resilient#head(path, options, callback)
Creates a HEAD request with optional custom options
resilient#setOptions(options)
Define custom options. See supported options
resilient#getOptions()
Return: Options
Retrieve the current options
resilient#setServiceOptions(options)
Define custom service-level options
resilient#setDiscoveryOptions(options)
Define custom service-level options
resilient#getHttpOptions(type)
Return: object
Get a map of HTTP specific options
resilient#servers([ type = 'servicee' ])
Return: Servers
Return a the current servers list. Allowed types are: service and discovery
resilient#discoveryServers([ servers ])
Return: Servers
Setter/Getter for discovery servers list
resilient#updateServers([ callback ])
Force to update the servers list from discovery servers, if they are defined, optionally passing a callback to handle the result
resilient#setHttpClient(fn)
Use a custom HTTP client as proxy instead of the embedded resilient native HTTP client.
Useful to define use proxy for custom frameworks or libraries in your existent project when you need to deal with some complex HTTP pre/post hooks logic and exploit custom HTTP client features
If defined, all the outgoing requests through Resilient client will be proxied to it.
Arguments passed to the client function:
- options
object- Resilient HTTP service options - callback
function- Request status handler. Expected arguments are:error,response
Note: error and response objects must be compatible with the current interface
resilient#restoreHttpClient()
Restore the native resilient HTTP client
resilient#on(event, handler)
Subscribe to an event. See supported events
resilient#off(event, handler)
Unsubscribe a given event and its handler. See supported events
resilient#once(event, handler)
Subscribe to an event with a given handler just once time. After fired, the handler will be removed
See supported events
resilient#flushCache()
Force to flush servers cache
resilient#client()
Return: Client
Returns an HTTP client-only interface. Useful to provide encapsulation from public usage and avoid resilient-specific configuration methods
resilient#areServersUpdated()
Return: boolean
Returns true if servers are up-to-date. Otherwise false
resilient#balancer([ options ])
Return: object
Returns the current balancer config options
resilient.VERSION
Type: string
Current semver library version
resilient.CLIENT_VERSION
Type: string
Current semver HTTP client library version
resilient.defaults
Type: object
Default config options
resilient.Servers(list)
Create a new servers store
resilient.Options(options)
Create a new options store
resilient.Client(resilient)
Creates a new resilient HTTP client with public API
Useful to provide encapsulation to the resilient API and expose only the HTTP client (the common interface the developers want to consum)
resilient.request(options [, cb])
Use the plain HTTP client
Contributing
Wanna help? Cool! It will be appreciated :)
You must add new test cases for any new feature or refactor you do, always following the same design/code patterns that already exist
Development
Only node.js is required for development
Clone the repository
$ git clone https://github.com/resilient-http/resilient.js.git && cd resilient.jsInstall development dependencies
$ npm installInstall browser dependencies
$ bower installGenerate browser bundle source
$ make browserRun tests (in a headless browser)
$ make testRun tests (in real browsers)
$ make karmaLicense
MIT © Tomas Aparicio and contributors