GithubHelp home page GithubHelp logo

reod / good-guy-http Goto Github PK

View Code? Open in Web Editor NEW

This project forked from schibsted-tech-polska/good-guy-http

0.0 2.0 0.0 90 KB

A good-guy HTTP client that handles caching, retrying and collapsing similar requests for you.

JavaScript 99.26% Shell 0.74%

good-guy-http's Introduction

good-guy-http

Build Status Coverage Status Dependency status

Good guy HTTP is an HTTP client library based on the request module, adding the following stuff on top:

  • easy promise-based interface
  • caching GET and other idempotent requests, either in-memory or using your chosen cache
    • this automatically obeys 'Cache-control' headers, but you can provide defaults for when it's missing
  • retrying failed requests
  • collapsing identical requests made at the same time into one
  • reporting HTTP error statuses as errors (promise rejections)
  • sane but strict defaults regarding timeouts etc.
  • implementation of the circuit breaker pattern
  • optional postprocessing of response to cache expensive parsing/munging operations
  • supports everything request supports by passing all the options to it

Good Guy HTTP

All of this is optional and you can opt-out of some or all of it.

Usage

var goodGuy = require('good-guy-http')();

// this request will get its response cached, will be retried if it fails, will be collapsed if you
// happen to make two of them
goodGuy('http://news.ycombinator.com').then(function(response) {
  console.log(response.body);
});

That's the basics. If you want to change the default behaviour, pass a configuration object:

// all of these are optional, the defaults are listed below
var goodGuy = require('good-guy-http')({
  maxRetries: 2,                     // how many times to retry failed requests
  collapseIdenticalRequests: true,   // should an identical request be collapsed into an ongoing one?
  allowServingStale: true,           // should goodguy return stale cached content after it expires?
                                     // it WILL be updated in the background either way, but if content that's
                                     // a bit stale is acceptable, your requests will appear to be much faster
  cache: ...,                        // cache object - see below for details         
  cacheResponseTimeout: 500          // how many ms to wait for the cache to respond before ignoring it completely
                                     // useful for remote caches (e.g. Redis)
  maximumResponseSize: 1024*1024     // any responses above this size will be rejected to prevent memory trouble,                                                                               
                                     // the default is 1MB
  errorLogger: console.error,        // error logging function - a failing cache doesn't break requests, but logs here
                                     // instead
  postprocess: false,                // pass a function here if you want to postprocess the response before caching/
                                     // returning it, e.g. function(res) { return JSON.parse(res.body); }
                                     // useful for ensuring that expensive parsing happens only once
  
  usePromise: require('bluebird'),   // Promise constructor to use, you may want to replace bluebird with 
                                     // different implementation, like q or native Promise
  
  defaultCaching: {                  // default caching settings for responses without Cache-Control                   
    cached: true,                    // - whether such responses should be cached at all
    timeToLive: 5000,                // - for how many ms
    mustRevalidate: false            // - is it OK to return a stale response and fetch in the background?
  },
  
  forceCaching: {...},               // uses the same properties as 'defaultCaching', but forces all requests
                                     // to use the settings (existing Cache-Control headers are IGNORED)
  
  clientErrorCaching: {              // how 4xx errors are treated with regards to caching
    cached: true,                    // they are cached by default, but you can opt out
    timeToLive: 60000,
    mustRevalidate: false
  },
  
  circuitBreaking: {                 // circuit breaking - if more than errorThreshold percent of requests fail 
    errorThreshold: 50               // good-guy stops sending them and periodically checks if the situation improves
  }                                  // you can set 'circuitBreaking: false' to turn this off
});

You can also pass options to the request module through this configuration object. Any options good guy doesn't recognize will be used to configure the underlying request object:

var goodGuy = require('good-guy-http')({
  timeout: 100 // that's request's timeout option
});

Good guy objects can also be reconfigured on the fly by adding good guy options to the request:

goodGuy({url: 'http://extremely-flaky-server.org', maxRetries: 10}).then(...);

The goodguy interface

Mirrors what request does almost exactly. Any object that the request module can handle can also be passed to good-guy-http. All options will be passed onto request. The get, post, etc. convenience methods are also present.

All functions support both a promise-based interface (when no callback is passed) and a traditional callback-based one (when a callback function is passed as the second parameter).

The response object that you will receive will not be a http.IncomingMessage, since those are difficult to cache. Instead, you will get a plain old object with statusCode, headers, body and httpVersion in all the same places they would be in normal responses.

Caches

Any object that has these methods can be used as a cache:

  • store(key, object) - returning a promise that resolves when the object is stored
  • retrieve(key) - returning a promise that resolves with the previously stored object, or undefined if no object is found

By default, an in-memory cache limited to the 500 most recently used requests is used, but you can easily override this:

var goodGuyLib = require('good-guy-http'); 

var goodGuy = goodGuyLib({cache: goodGuyLib.inMemoryCache(10)});  // smaller in-memory cache
var goodGuy = goodGuyLib({cache: false});                         // disable caching altogether
var goodGuy = goodGuyLib({cache: customCache});                   // your custom implementation based on Redis/Mongo/Bitcoin blockchain

Circuit breaker

To avoid overloading external services that are having trouble coping with the load, good-guy-http uses a circuit breaker (based on Yammer's circuit-breaker-js) by default. Each host is treated as a separate service and has a separate circuit breaker.

Once the breaker trips (too many failures), your requests will start failing with a CircuitBrokenError. It can be easily identified by having the code property set to ECIRCUIT. Once the situation improves, requests will start going through normally again.

You can configure the error threshold or turn the whole feature off:

var goodGuyLib = require('good-guy-http'); 

var goodGuy = goodGuyLib({
  circuitBreaking: { errorThreshold: 75 }; // only break the circuit when 75% or more requests fail
});
var goodGuy = goodGuyLib({circuitBreaking: false}); // no circuit breaking, please

good-guy-http's People

Contributors

jakubwasilewski avatar kjarmicki avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.