RESTful JavaScript client w kwadrans
Próbowałem restful.js, próbowałem jQuery REST client, aż ostatecznie dałem sobie spokój. Dla mnie były jakieś trudne/ciężkie w użyciu. A czym powinien być REST client? Cienkim wrapperem na dowolnego klienta HTTP, który gada z dowolnym url-em.
Na własne potrzeby założyłem, że:
- interfejs ma być banalnie prosty w użyciu
- wystarczy obsługa tylko content type application/json
- ma być obsługa nagłówków, także defaultowych (żeby się nie powtarzać)
- dozwolona jest zależność od jQuery (można się tego względnie łatwo wyzbyć)
Powstał prototyp:
var RestAPI = function(url, params) {
var absoluteUrlPattern = /^https?:\/\//i,
self=this,
params = params || {};
this.defaultHeaders = params.headers || {};
this.url = url;
function isAbsoluteUrl(url) {
return absoluteUrlPattern.test(url);
}
function resourceToUrl(resource) {
resource = resource || '';
if(isAbsoluteUrl(resource)) {
return resource;
} else {
return self.url+'/'+resource;
}
}
function makeResponseObject(jqXhr, data) {
var headers = {},
headersList = jqXhr.getAllResponseHeaders().split('\r\n');
$.each(headersList, function(i, headerStr) {
var headerTuple = headerStr.split(': ');
if(headerTuple[0]) {
headers[headerTuple[0].toLowerCase()] = headerTuple[1];
}
});
return {
status: jqXhr.status,
statusText: jqXhr.statusText,
headers: headers,
data: data
};
}
function doMethod(type, resource, data, headers) {
var dfr = $.Deferred(),
completeHeaders = $.extend({}, self.defaultHeaders, headers);
$.ajax({
url: resourceToUrl(resource),
type: type,
dataType: 'json',
contentType: 'application/json',
headers: completeHeaders,
data: typeof(data)!=='undefined' && data!==null ? JSON.stringify(data) : null
}).then(function(respData,respStatus,jqXhr) {
dfr.resolve(respData, makeResponseObject(jqXhr, respData));
}, function(jqXhr) {
dfr.reject(makeResponseObject(jqXhr));
});
return dfr.promise();
};
this.get = function(resource, params, headers) {
return doMethod('GET', resource, params, headers);
}
this.post = function(resource, payload, headers) {
return doMethod('POST', resource, payload, headers);
}
this.put = function(resource, payload, headers) {
return doMethod('PUT', resource, payload, headers);
}
this.patch = function(resource, payload, headers) {
return doMethod('PATCH', resource, payload, headers);
}
this['delete'] = function(resource, headers) {
return doMethod('DELETE', resource, null, headers);
}
}
Działa? Działa, i to ciekawie.
Przykład - kto mnie śledzi na GitHub?
var github = new RestAPI('https://api.github.com');
github.get('users/marcinn').then(function(user) {
github.get(user.followers_url).then(function(followers) {
console.log(followers);
});
});
Koniec, kropka. Prosto i na temat. Pobawta się sami na plunkr.
Jak kogo interesuje - publikuję na licencji “Brać! Mać…” oczywiście bez żadnej gwarancji. Wspomnijta w creditsach, że był taki Nowak, któremu to się klepać kodu nie chciało.
I jeszcze jedno - skoro się niektórzy chwalą filesize, to ja też podam:
- Original: 2370 bytes
- Gzipped: 764 bytes
Niech przebijają.
A AngularJS i jego ngResource albo nawet Restangular? Głupotą jest mapowanie REST na CRUD (albo stosowanie active record). W REST mamy dobrze określone VERBS. Nie ma wśród nich save. I tyle w temacie.
Opublikowano w kategoriach