Consuming RESTful Resources with AngularJS

by @PeterPeerdeman from

Lifely

Background

Online Technology Consultant

Internet Banking

Multiplatform mobile app

"Coderende eindbaas"

App backend design

REST / AngularJS awesomeness

So, who knows about REST?

Representational State Transfer (REST)

  • GET
  • POST
  • DELETE
  • PUT
  • PATCH
  • OPTIONS
  • LINK
  • TRACE

Difference between PUT and PATCH?


PUT /customers/1
{
	'id':1,
	'name':'Peter',
	'shoesize': 46
}
    					

PATCH /customers/1
{
	'name':'Peter'
}
    					

REST

separates back- and frontend

  • Easily integrate data in (web) apps
  • Easily replace (web) app
  • Third party access
  • Data purity

AngularJS - $resource

Saves you from writing a whole lot of AJAX code

Get customers establishment & update


var Customer = $resource('/api/v1/customers/:customerId', {customerId:'@id'});

//performs GET /api/v1/customers/123
$scope.customer = Customer.get({customerId:123}, function() {
    //callback
});
    				

var Establishment = $resource('/api/v1/customers/:customerId/ ' +
'establishments/:establishmentId', {customerId:123, establishmentId:'@id'});
 
//performs GET /api/v1/customers/123/establishments/
 var establishments = Establishment.query(function() {
   var establishment = _.find(establishments, {city:'Amsterdam'});
   establishment.name = "Hippo HQ";
   establishment.$save();
 });
    				

AngularJS - $resource


    Good:

  • Creates resource object to interact with RESTful resources

  • Bad:

  • Doesnt handle sub resources
  • requires full url in each object
  • Doesnt support all REST methods
  • Limited options

Restangular

Configure, retrieve and update


RestangularProvider.setBaseUrl('/api/v1')
    				

//performs GET /api/v1/customers/123
Restangular.one('customers', 123).get().then(function(customer) {
  $scope.customer = customer
});
    				

//performs GET /api/v1/customers/123/establishments
$scope.customer.getList('establishments').then(function(establishments) {
   var establishment = _.find(establishments, {city:'The Hague'});
   establishment.name = "Q42";
   establishment.put();
});
    				

post a new establishment


var newEstablishment = {name:'Lifely', address:'zekeringstraat 17'};

//performs POST /api/v1/customers/123/establishments
$scope.customer.getList('establishments').post(newCustomer).then(function(data) { 
	newCustomer.id = data.id;
  	$scope.customer.establishments.push(newEstablishment);
})
    				

perform custom verb on subresource


//performs POST /api/v1/customers/favorite
$scope.customer.customPost({}, 'favorite');
    				

(un) wrap resources


//e.g. our services return 
//single resource {user:{name:'peter'}}
//list resource {data:[{name:'peter'}]
Restangular.setResponseInterceptor(function(response, operation, what) {
  var newResponse;
  if (operation === "getList") {
    // This is a wrapped array
    newResponse = response.data;
  } else {
    // This is a wrapped element
    newResponse = response[what];
  }
  return newResponse;
});
    				

remove _id field on PUT


RestangularProvider.setRequestInterceptor(
  function(elem, operation, what) {        
    if (operation === 'put') {
      elem._id = undefined;
      return elem;
    }
    return elem;
});
    				

Concluding words

  • Separate backend and frontend
  • Adhere to REST and design API URLs carefully
  • Give AngularJS and Restangular a shot

Props & Links

  • Props for creating Restangular and sharing to @mgonto

Restangular

Start consuming!

Thank you for your attention

Consuming RESTful Resources with AngularJS

by @PeterPeerdeman from

Lifely