Skip to content

Instantly share code, notes, and snippets.

@weswigham
Last active February 25, 2016 13:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save weswigham/c142911ba4293d8f47b6 to your computer and use it in GitHub Desktop.
Save weswigham/c142911ba4293d8f47b6 to your computer and use it in GitHub Desktop.
resteasy.js - Makes consuming rest interfaces as data promises super simple
(function(window) {
//Step 1: Promised wrapper for XMLHTTPRequest
function Request(url, options) {
return new Promise(function(resolve, reject) {
if (!options) {
if (typeof(url) == "string") {
options = { url: url };
} else {
options = url;
}
} else {
options.url = url;
}
var req = new XMLHttpRequest();
req.timeout = options.timeout || 0;
req.ontimeout = function() {
reject(new Error('Request timed out!'));
};
req.withCredentials = options.withCredentials;
req.open(options.method || 'GET', options.url, true, options.user, options.password);
Object.keys(options.headers || {}).forEach(function(key){
req.setRequestHeader(key, options.headers[key]);
});
req.onreadystatechange = function(e) {
var obj;
if(req.readyState !== 4) {
return;
}
if([200,304].indexOf(req.status) === -1) {
return reject(new Error('Server responded with a status of ' + req.status));
} else {
var expect = options.expect || 'anything';
switch(expect.toLowerCase()) {
case 'json':
try {
obj = JSON.parse(e.target.responseText);
} catch (_) {
return reject(new Error('JSON parsing error.'));
}
return resolve(obj);
case 'xml':
return resolve(e.target.responseXML);
default:
return resolve(e.target.response);
}
}
};
if (options.mimetype) {
req.overrideMimeType(options.mimetype);
}
req.send(options.data || '');
});
}
//Step 2: location-protcol-aware wrapper for http(s) requests
function LocationRequest(hostpath, options) {
options = options || {};
var protocol = window.location.protocol;
if (options.forceSSL) {
protocol = 'https:';
}
var url = protocol + '//' + hostpath;
return Request(url, options);
}
//Step 3: RESTy defaults wrapper
function RESTRequest(hostpath, options) {
options = options || {};
options.method = options.method || 'GET';
options.expect = options.expect || 'json';
if (options.forceSSL === undefined) {
options.forceSSL = true;
}
return LocationRequest(hostpath, options);
}
//Step 3.5: Proxy shim
if (!window.Proxy) {
console.warn('No Proxy object found, RESTEasy cannot be used.');
return; //All is for naught, no proxy present
}
var LocalProxy = Proxy;
if (typeof(Proxy) !== 'function') {
LocalProxy = function(target, handlers) {
if (target instanceof Function) {
return Proxy.createFunction(handlers, target);
} else {
return Proxy.create(handlers, target);
}
};
}
function isObject(obj) { //From underscore.js
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
function extend(obj) { //From underscore.js
if (!isObject(obj)) return obj;
var source, prop;
for (var i = 1, length = arguments.length; i < length; i++) {
source = arguments[i];
for (prop in source) {
if (hasOwnProperty.call(source, prop)) {
obj[prop] = source[prop];
}
}
}
return obj;
}
//Step 4: Proxy
function RESTEasy(host, path, upperoptions) {
if (isObject(path)) {
upperoptions = path;
path = undefined;
}
var handlers = {
get: function(target, key) {
return new RESTEasy(host, (path || '')+'/'+key, upperoptions);
}
};
return new LocalProxy(function(queryhash, options) {
var query = '';
if (queryhash) {
var queryitems = [];
for (var key in queryhash) {
queryitems.push(encodeURIComponent(key) + '=' + encodeURIComponent(queryhash[key]));
}
query = '?' + queryitems.join('&');
}
if (path) {
return RESTRequest(host+path+query, extend({}, upperoptions, options));
}
return RESTRequest(host+query, extend({}, upperoptions, options));
}, handlers);
}
//Step 5: Export
var noConflict = window.RESTEasy;
RESTEasy.noConflict = function() {
window.RESTEasy = noConflict;
return RESTEasy;
};
window.RESTEasy = RESTEasy;
//Step 6: ???
//Step 7: Profit!
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment