Sign Up for Free

RunKit +

Try any Node.js package right in your browser

This is a playground to test code. It runs a full Node.js environment and already has all of npm’s 400,000 packages pre-installed, including restglue with all npm packages installed. Try it out:

var restglue = require("restglue")

This service is provided by RunKit and is not affiliated with npm, Inc or the package authors.

restglue v1.0.23

multi-api restful client (javascript) with glue, using superagent & promises (lightweight, no buildchain needed)

Build Status RESTGLUE: multi-api restful client using superagent & promises


<script type="text/javascript" src=""></script> <!-- older browsers -->
<script type="text/javascript" src="dist/restglue.min.js"></script>

or in nodejs just do npm install restglue superagent and then:

var restglue = require('restglue')

Example: single api

var myapi = new restglue()
myapi.headers['Content-Type'] = 'application/json'

Not really exciting yet, but now you can do calls like so:
.then( function(json){  // json-result of GET /pizza
                        // call json.getResponse() for raw response (headers etc)
.catch( function(err){
  console.log("could not get pizza")

NOTE: use new restglue("") to automatically prepend an external apiurl to all endpoints, and make sure you got CORS setup on your server when doing requests from the browser.

Restful endpoint function reference

getAll(query, headers)                - will do GET     /pizza
post(payload, query, headers)         - will do POST    /pizza      {..}
get(id, query, headers)               - will do GET     /pizza/{id}
put(id, payload, query, headers)      - will do PUT     /pizza/{id} {..}
delete(id, payload, query, headers)   - will do DELETE  /pizza/{id} {..}
patch(id, payload, query, headers)    - will do PATCH   /pizza/{id} {..}
options(id, payload, querym headers)  - will do OPTIONS /pizza/{id} {..}

NOTE: query and headers are optional and are used only for that request.

Custom endpoints + monkeypatch = restglue.prototype.request.bind( this, "post",  '/foo/bar',  {payload:true}, {queryfoo:1, querybar:2}, {X-HEADER-FOO:12} )  = restglue.prototype.request.bind( this, "get",  '/foo/bar' )

Also, you can monkeypatch these function to alter restglue's behaviour:

restglue.prototype.addEndpointg( resourcename  )
restglue.prototype.requestg(method, url, payload, query, headers)

Offline sandbox

You can fake responses (for offline development etc) in 2 ways, like so:


myapi.sandboxUrl('/foobar',       {'data':{"foo":true}}  ) 
myapi.sandboxUrl('/myapi',        {'path':"/js/sandbox"} )
myapi.sandboxUrl( /some.*regex/,  "/js/foo" )

  // data = {"foo":true}
  // data = /js/sandbox/foo/get.json instead of GET {apiurl}/myapi/foo 

NOTE: {apiurl} is passed using new restglue({apiurl:""})

Chained endpoints, multiple api's

Byebye async spaghetti, welcome clean code.

Combine multiple endpoints into one call: = myapi.compose([
  function(i)  { return{"sort":"-date_create"})    },
  function(res){ return otherapi.getRanking(res.cook.profile_url)      },
  function(res){ return res.score                                      }
])("foo") function(res){
  // res is '4'
}).catch( function(err){ ..  })

Example: query args {"sort":"-date_create"} )
.then( function(res){
  // result of GET /pizza?sort=-date_create
var password = "bar"
myapi.headers['Authorization'] = 'Basic '+btoa( login+":"+password )

// do calls

Example: response headers
.then( function(res){
  var headers = res.getResponse().headers

NOTE: Make sure you have CORS configured properly on your server, otherwise certain headers won't be accessible in javascript.

Example: hooks

beforeRequest and afterRequest allow you to massage the request or response

myapi.beforeRequest( function(config){
  // format the input for an exotic api, before doing the actual request
  config.payload = { type: "payload", payload:config.payload } 

Here's how to simply prevent unnecessary calls

var cache = {get:{}}

myapi.beforeRequest( function(config){
  if( config.method == "get" && cache.get[config.url] ) return cache.get[config.url]

myapi.afterRequest( function(config, res, err){
  if( config.method == "get" && !err ) cache.get[ config.url ] = res

NOTE: optionally you can store a new Date().getTime() timestamp, and bypass the cache when expired

Example: Multi-api and mult-versioned wrappers

This easifies iterative, backwardscompatible development:

function getApi(){
  var v1       = new restglue(""),
  var v2       = new restglue(""),
  var api      = {
    ga: new restglue("") 

  // *TODO* call addEndpoint(...) on v1,v2 and googleanalytics

  // ok, we're assuming the v1 and v2 endpoints are setup 
  // so now we set v1 endpoints as default 
  for( i in v1 ) api[i] = v1[i]

  // but upgrade the pizza endpoint to v2 = 

  return api 

var myapi = getApi()

Example: HTTP auth

var login          = "foo"
var password       = "bar"

myapi.headers['Authorization'] = 'Basic '+btoa( login+":"+password
.then( function(res){

  // authenticated response

.catch( function(err){

Example: HTTP auth + bearer token

var login          = "foo"
var password       = "bar"


myapi['user/current'].getAll(false, { 'Authorization': 'Basic '+btoa( login+":"+password ) })
.then( function(res){

  if( ! res.bearer_hash ) throw new Exception("AUTH_FAILED")
  myapi.headers['Authentication'] = "bearer "+res.bearer_hash 

.catch( function(err){

Why superagent and not fetch?

Eventhough I prefer fetch, this module relies on superagent and not on fetch because:

  • I had some weird experiences with fetch-polyfill vs native fetch (I guess it needs a bit of time)
  • XHR request seems a more robust choice before fetch really takes over
  • superagent seems battletested and has a lot of extensions and plugins

Also i noticed projects like restful.js, frisbee, superagent-defaults, superagent-jsonapify,superagent-ls,superapi, superagent-pool, super-res

but I needed a little bit more and less, in short I need:

  • a drop-in solution (not all js devs have ES6/ES7 transpilertoolchain-experience)
  • easy chaining of endpoints, from multiple api's (hence async helpers included)
  • promises
  • requestpool cache but with TTL (hence the hooks, so the beforeRequest-hook can return a cached response)
  • compose a superapi (swap around endpoint versions)
RunKit is a free, in-browser JavaScript dev environment for prototyping Node.js code, with every npm package installed. Sign up to share your code.
Sign Up for Free