httpi - A Lightweight $resource-Inspired Module For AngularJS

As I blogged about before, I'm not a huge fan of the $resource module in AngularJS. But, it does have some features that I do like; namely, URL interpolation and the encapsulation of URLs across requests to the same resource. I created the "httpi" module in an attempt to build these features on top of the $http service while still providing direct access to the flexibility of the $http service underneath.

View the httpi project on my GitHub account.

The httpi service is really just a preprocessor for the underlying $http service. It takes your configuration object, interpolates the URL (hence the "i" in "httpi"), and then passes the updated configuration object off to $http. It then returns the same promise that the $http service returned to it.

The httpi service can also create $resource-inspired objects that apply the same URL across different HTTP calls. But, like the httpi service, each HttpiResource instance method takes a normal configuration object, modifies it, and then passes it off to the underlying $http service.

NOTE: When I say "$resource-inspired," I do so very loosely. I do not mean to imply that I am recreating the $resource feature-set; rather, that I am extracting what I personally found useful in the $resource-oriented approach.

To see this in action, take a look at the code below (which is the example on my GitHub project page). I'm creating an httpi resource and then invoking several of the convenience methods:

<!doctype html> <html ng-app="Demo"> <head> <meta charset="utf-8" /> <title> Using The httpi Service To Make AJAX Requests In AngularJS </title> </head> <body ng-controller="DemoController"> <h1> Using The httpi Service To Make AJAX Requests In AngularJS </h1> <!-- Initialize scripts. --> <script type="text/javascript" src="vendor/angular-1.2.16.min.js"></script> <script type="text/javascript" src="../lib/httpi.js"></script> <script type="text/javascript"> // Define the module for our AngularJS application. var app = angular.module( "Demo", [ "httpi" ] ); // -------------------------------------------------- // // -------------------------------------------------- // // I control the main demo. app.controller( "DemoController", function( $scope, httpi ) { console.warn( "None of the API endpoints exist - they will all throw 404." ); // NOTE: The (.|.) notation will be stripped out automatically; it's only // here to improve readability of the "happy paths" for interpolation // labels. The following urls are pre-processed to be identical: // -- // api/friends/( :listCommand | :id/:itemCommand ) // api/friends/:listCommand:id/:itemCommand var resource = httpi.resource( "api/friends/( :listCommand | :id/:itemCommand )" ); // Clear list of friends - matching listCommand. resource.post({ data: { listCommand: "reset" } }); // Create a new friend - no matching URL parameters. resource.post({ data: { name: "Tricia" } }); // Get a given friend - ID matching. resource.get({ data: { id: 4 } }); // Make best friend - ID, itemCommand matching. resource.post({ data: { id: 4, itemCommand: "make-best-friend" } }); // Get gets friends - no matching URL parameters. resource.get({ params: { limit: "besties" } }); // Get a friend as a JSONP request. // -- // NOTE: The "resource" will auto-inject the "JSON_CALLBACK" marker that // AngularJS will automatically replace with an internal callback name. resource.jsonp({ data: { id: 43 } }); } ); </script> </body> </html>

Notice that the configuration objects passed into the "resource" methods don't have to include the Method or URL properties - these are automatically interpolated and injected into the configuration object before they are passed-off to the underlying $http service.

When we run the above code, we get the following network activity:

POST /api/friends/reset

POST /api/friends

GET /api/friends/4

POST /api/friends/4/make-best-friend

GET /api/friends?limit=besties

GET /api/friends/43?callback=angular.callbacks._0

Of course, you don't have to use the resource part of the module; the resource is kind of like a preprocessor for the httpi service which is, itself, a preprocessor for the $http service. If you call the httpi service directly, you'll still get the URL interpolation - you simply have to pass-in the URL with each request.

Obviously, the value of this module is heavily colored by my own experience with the $resource module in AngularJS. If you're loving $resource, I am not suggesting that you stop using it. But, for me personally, it wasn't a huge value-add. So, I tried to take the parts that I did like and rebuild them on top of the $http service in a very transparent way.

Tweet This Fascinating post by @BenNadel - httpi - A Lightweight $resource-Inspired Module For AngularJS Woot woot — you rock the party that rocks the body!







