build rest api clients for angularjs

58
Build REST API client like a BOSS Build RESTful API clients for AngularJS, the proper way

Upload: almog-baku

Post on 18-Jul-2015

326 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Build REST API clients for AngularJS

Build REST API client like a BOSSBuild RESTful API clients for AngularJS, the proper way

Page 2: Build REST API clients for AngularJS

Who are you?

@AlmogBaku nice to meet ya`

1. Entrepreneur

2. Co-Founder & CTO @ Rimoto

3. Developer for 10 years

4. GitHub addicted.

5. Blog about entrepreneurship and development:

www.AlmogBaku.com

Page 3: Build REST API clients for AngularJS

What are we going to talk about?

● What tha’ heck is REST?

● Why $resource is sucks?

● $http

● Say hi to Restangular

● Do it like a boss

Page 4: Build REST API clients for AngularJS

Disclaimer

You wanna know more? Google it!

Page 5: Build REST API clients for AngularJS

What tha’ heck is REST?

Representational State Transfer

Page 6: Build REST API clients for AngularJS

Watttt??

Page 7: Build REST API clients for AngularJS

What is API?

API is a layer that connects two applications.

Application Programing Interface

Page 8: Build REST API clients for AngularJS

What is API?

API is actually a common language, that

both of the parties knows.

Page 9: Build REST API clients for AngularJS

REST

REST is a Client-Server API

Page 10: Build REST API clients for AngularJS

REST

REST is just the regular way the internet works!

GET http://google.com/

Page 11: Build REST API clients for AngularJS

REST

REST is just the regular way the internet works!

GET http://google.com/RESPONSE 200 OK

Page 12: Build REST API clients for AngularJS

REST

REST is about resources, not about functions.

Book store api:

1. /api/authors/2. /api/authors/:authorId/3. /api/authors/:authorId/books/4. /api/authors/:authorId/books/:bookId5. /api/authors/:authorId/books/:bookId/reviews6. /api/authors/:authorId/books/:bookId/reviews/:reviewId

Page 13: Build REST API clients for AngularJS

REST

REST is about resources, not about functions.

Book store api:

1. /api/authors/2. /api/authors/:authorId/3. /api/authors/:authorId/books/4. /api/authors/:authorId/books/:bookId5. /api/authors/:authorId/books/:bookId/reviews6. /api/authors/:authorId/books/:bookId/reviews/:reviewId

Page 14: Build REST API clients for AngularJS

REST

GET /api/authors/

[ { "id": 7, "name": "J.R.R. Tolkien", "birthday": "1-3-1892" }, { "id": 183, "name": "Douglas Adams", "birthday": "3-11-1952" }]

Page 15: Build REST API clients for AngularJS

REST

REST is about resources, not about functions.

Book store api:

1. /api/authors/2. /api/authors/:authorId/3. /api/authors/:authorId/books/4. /api/authors/:authorId/books/:bookId5. /api/authors/:authorId/books/:bookId/reviews6. /api/authors/:authorId/books/:bookId/reviews/:reviewId

Page 16: Build REST API clients for AngularJS

REST

GET /api/authors/187/

{ "id": 183, "name": "J.R.R. Tolkien", "full_name": "John Ronald Reuel Tolkien", "birthday": "1-3-1892", "genre": "SciFi"}

Page 17: Build REST API clients for AngularJS

REST

The same URIs can do many different actions...

We can request web pages in one of the following methods:

1. GET - request information about resource

2. POST - create new resource

3. PUT - update resource

4. DELETE - delete resource

5. HEAD - get information only with headers (eg. if resource exists)

6. OPTIONS - list of available methods to the resource (like --help)

Page 18: Build REST API clients for AngularJS

REST

Errors are simple http errors

200 - OK

404 - Not found

401 - Unauthorized

500 - Server Error

Etc.

Page 19: Build REST API clients for AngularJS

REST

REST is Stateless

- You can’t use cookies

- You need to pass your identification in every request

GET /users/me?access_token=ftjhi89uh5982hbrvt92vgt9qvhg2r0219

Page 20: Build REST API clients for AngularJS

REST API+

Page 21: Build REST API clients for AngularJS

REST with AngularJS

It’s pretty simple actually.. just use $resource

var Author = $resource('/api/v1/author/:authorId', {authorId:'@id'});Author.get({authorId:183}, function(author) { author.name = 'J.R.R. Tolkien'; author.$save();});

Page 22: Build REST API clients for AngularJS

The thing is…It just sucks

Page 23: Build REST API clients for AngularJS

The thing is…It just sucks

1. It can be very complex...

var Author = $resource('https://api.rimoto.net/api/v1/author/:authorId', {authorId:'@id'});Author.get({authorId:183}, function(author) { author.name = 'J.R.R. Tolkien'; author.$save();});

var Book = $resource('https://.../api/v1/author/:authorId/books/:bookId', {authorId: 183, bookId:'@id'});Book.get({bookrId:2}, function(book) { book.name = 'Lord of the rings'; book.$save();});

Page 24: Build REST API clients for AngularJS

The thing is…It just sucks

2. Doesn’t allow you to parse the API3. No way to set base url application wide4. You can’t handle errors application wide5. You can’t handle headers application wide6. You can’t handle anything application wide

Actually- $resource is okay for anything other than serious apps.

Page 25: Build REST API clients for AngularJS

What can we do?

We can use $http, in order to add necessary headers:

We can also use the $http interceptor, in order to handle errors...

var req = { method: 'POST', url: 'http://example.com', headers: { 'Content-Type': 'application/json' }, data: { test: 'test' }};$http(req).success(function(){...}).error(function(){...});

Page 26: Build REST API clients for AngularJS

What can we do?

We can also use the $http interceptor, in order to handle errors...

$provide.factory('myHttpInterceptor', function($q, dependency1) { return { 'requestError': function(rejection) { // do something on error if (canRecover(rejection)) { return responseOrNewPromise } return $q.reject(rejection); }, 'response': function(response) { //parsing here.... return response; }, 'responseError': function(rejection) { // do something on error if (canRecover(rejection)) { return responseOrNewPromise } return $q.reject(rejection); } };});$httpProvider.interceptors.push('myHttpInterceptor');

Page 27: Build REST API clients for AngularJS

What can we do?

We can also use the $http interceptor, in order to handle errors...

$provide.factory('myHttpInterceptor', function($q, dependency1) { return { 'requestError': function(rejection) { // do something on error if (canRecover(rejection)) { return responseOrNewPromise } return $q.reject(rejection); }, 'response': function(response) { //parsing here.... return response; }, 'responseError': function(rejection) { // do something on error if (canRecover(rejection)) { return responseOrNewPromise } return $q.reject(rejection); } };});$httpProvider.interceptors.push('myHttpInterceptor');

Page 28: Build REST API clients for AngularJS

What can we do?

We can also use the $http interceptor, in order to handle errors...

$provide.factory('myHttpInterceptor', function($q, dependency1) { return { 'requestError': function(rejection) { // do something on error if (canRecover(rejection)) { return responseOrNewPromise } return $q.reject(rejection); }, 'response': function(response) { //parsing here.... return response; }, 'responseError': function(rejection) { // do something on error if (canRecover(rejection)) { return responseOrNewPromise } return $q.reject(rejection); } };});$httpProvider.interceptors.push('myHttpInterceptor');

Page 29: Build REST API clients for AngularJS

What can we do?

We can also use the $http interceptor, in order to handle errors...

$provide.factory('myHttpInterceptor', function($q, dependency1) { return { 'requestError': function(rejection) { // do something on error if (canRecover(rejection)) { return responseOrNewPromise } return $q.reject(rejection); }, 'response': function(response) { //parsing here.... return response; }, 'responseError': function(rejection) { // do something on error if (canRecover(rejection)) { return responseOrNewPromise } return $q.reject(rejection); } };});$httpProvider.interceptors.push('myHttpInterceptor');

Page 30: Build REST API clients for AngularJS
Page 31: Build REST API clients for AngularJS

Say hi to

Restangular

Page 32: Build REST API clients for AngularJS

Restangular

1. Restangular solves ‘em all!

2. Published on 2013

3. Very stable and popular angular-module

4. Active community

5. Allows you to configure your REST API in application level

6. Restangular 2 will support AngularJS 2! (WIP)

7. Very easy to use

Page 33: Build REST API clients for AngularJS

Configurations

Define initial settings:

Defining base url:

Defining Content-Type headers:

RestangularProvider.setBaseUrl('http://api.rimoto.net/api/v1/');

RestangularConfigurer.setDefaultHeaders({'Content-Type': 'application/json'});

Page 34: Build REST API clients for AngularJS

Say hi to Restangular

Let’s create a new author:

var Authors = Restangular.all('authors');Authors.post({ name: "J.R.R. Tolkien"});

Page 35: Build REST API clients for AngularJS

Say hi to Restangular

Lets’ create a new author:

var Authors = Restangular.all('authors');Authors.post({ name: "J.R.R. Tolkien"});

POSThttp://api.rimoto.net/api/v1/authors/

Page 36: Build REST API clients for AngularJS

Say hi to Restangular

Lets’ create a new author:

var Authors = Restangular.all('authors');Authors.post({ name: "J.R.R. Tolkien"});

Page 37: Build REST API clients for AngularJS

Say hi to Restangular

Get the author:

Restangular.one('authors', 183).get() .then(function(author) { $scope.author = author; });

Page 38: Build REST API clients for AngularJS

Say hi to Restangular

Get the author:

Restangular.one('authors', 183).get() .then(function(author) { $scope.author = author; });

GEThttp://api.rimoto.net/api/v1/authors/183

Page 39: Build REST API clients for AngularJS

Say hi to Restangular

Get all his books:

$scope.author.getList('books') .then(function(books) { var firstBook = books[0]; firstBook.name="The Hobbit"; firstBook.put(); });

Page 40: Build REST API clients for AngularJS

Pretty simple.. huh?

Page 41: Build REST API clients for AngularJS

Model parsing

RestangularConfigurer.ExtendModel("books", function(book) { book.published = new Date(book.published); return book;});

We can “transform” data from our API to javascript!

Page 42: Build REST API clients for AngularJS

Model parsing

<div class="vote-box"> <button ng-click="voteUp($review)" class="up"><i class="up-arrow"></i></button> <div>{{votes|number}}</div> <button ng-click="voteDown($review)" class="down"><i class="down-arrow"></i></button></div>

Page 43: Build REST API clients for AngularJS

Model parsing

<div class="vote-box"> <button ng-click="voteUp($review)" class="up"><i class="up-arrow"></i></button> <div>{{votes|number}}</div> <button ng-click="voteDown($review)" class="down"><i class="down-arrow"></i></button></div>

Vote done on the controller

Page 44: Build REST API clients for AngularJS

Model function

But it’s an API function!

Page 45: Build REST API clients for AngularJS

Model parsing

How can we solve that?

Page 46: Build REST API clients for AngularJS

Model parsing

How can we solve that?

1. Create a transformer2. Add the function to the model!3. Fin.

Page 47: Build REST API clients for AngularJS

Model parsing

How can we solve that?

1. Create a transformer2. Add the model this function!3. Fin.

RestangularConfigurer.ExtendModel("review", function(review) { review.voteUp = function() { return review.getAll("votes").post({ vote_up: true }); }; return review;});

Page 48: Build REST API clients for AngularJS

Model parsing

We can do use this tool for many cases:

1. Ordering lists2. Special parsing3. Add functions4. Etc.

Page 49: Build REST API clients for AngularJS

What about errors?

RestangularConfigurer.setErrorInterceptor(function(response) { if([401, 403, 405].indexOf(response.status)!=-1) { logout(); return false; }});

Page 50: Build REST API clients for AngularJS

Build REST client like a BOSS

Page 51: Build REST API clients for AngularJS

PRO tips

Bundle your whole API as “SDK”, and extend the Restangular to be your own API service:

module .factory('API', ['Restangular', function(Restangular) { angular.extend(this, Restangular.withConfig(function(RestangularConfigurer) { RestangularConfigurer.setBaseUrl("https://api.rimoto.net"); RestangularConfigurer.setRequestSuffix('/'); RestangularConfigurer.setDefaultHeaders({ Accept: 'application/json;v=1' }); }));

return this; }]);

Page 52: Build REST API clients for AngularJS

PRO tips

1. You can set the `id` parameter (eg. for mongodb):

RestangularProvider.setRestangularFields({ id: '_id'});

Page 53: Build REST API clients for AngularJS

PRO tips

2. Handle the Access-Tokens on application level

Example for Restangular with ngAuth:

/** Login changed **/$rootScope.$on("Auth.status", function(event, response) { if(response.access_token) { Restangular.setDefaultRequestParams({ access_token: response.access_token }); } else { Restangular.setDefaultRequestParams({ access_token: null }); }});

Page 54: Build REST API clients for AngularJS

PRO tips

3. Decouple Restangular to models

4. You can define Restangular to use HATEOAS

5. Keep your API service generic, and handle specific use-cases separately.

module.factory('Users', function(Restangular) { return Restangular.service('users');});

RestangularProvider.setRestangularFields({ selfLink: 'self.link'});

Page 55: Build REST API clients for AngularJS

Check it out

github.com/mgonto/restangular

Page 56: Build REST API clients for AngularJS

Be creative,and create your own API

Page 57: Build REST API clients for AngularJS

Questions?

Page 58: Build REST API clients for AngularJS

Thanks.