SlideShare a Scribd company logo
1 of 58
Download to read offline
Build REST API client like a BOSS
Build RESTful API clients for AngularJS, the proper way
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
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
Disclaimer
You wanna know more? Google it!
What tha’ heck is REST?
Representational State Transfer
Watttt??
What is API?
API is a layer that connects two applications.
Application Programing Interface
What is API?
API is actually a common language, that
both of the parties knows.
REST
REST is a Client-Server API
REST
REST is just the regular way the internet works!
GET http://google.com/
REST
REST is just the regular way the internet works!
GET http://google.com/RESPONSE 200 OK
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/:bookId
5. /api/authors/:authorId/books/:bookId/reviews
6. /api/authors/:authorId/books/:bookId/reviews/:reviewId
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/:bookId
5. /api/authors/:authorId/books/:bookId/reviews
6. /api/authors/:authorId/books/:bookId/reviews/:reviewId
REST
GET /api/authors/
[
{
"id": 7,
"name": "J.R.R. Tolkien",
"birthday": "1-3-1892"
},
{
"id": 183,
"name": "Douglas Adams",
"birthday": "3-11-1952"
}
]
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/:bookId
5. /api/authors/:authorId/books/:bookId/reviews
6. /api/authors/:authorId/books/:bookId/reviews/:reviewId
REST
GET /api/authors/187/
{
"id": 183,
"name": "J.R.R. Tolkien",
"full_name": "John Ronald Reuel Tolkien",
"birthday": "1-3-1892",
"genre": "SciFi"
}
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)
REST
Errors are simple http errors
200 - OK
404 - Not found
401 - Unauthorized
500 - Server Error
Etc.
REST
REST is Stateless
- You can’t use cookies
- You need to pass your identification in every request
GET /users/me?access_token=ftjhi89uh5982hbrvt92vgt9qvhg2r0219
REST API
+
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();
});
The thing is…
It just sucks
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();
});
The thing is…
It just sucks
2. Doesn’t allow you to parse the API
3. No way to set base url application wide
4. You can’t handle errors application wide
5. You can’t handle headers application wide
6. You can’t handle anything application wide
Actually- $resource is okay for anything other than serious apps.
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(){...});
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');
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');
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');
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');
Say hi to
Restangular
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
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'});
Say hi to Restangular
Let’s create a new author:
var Authors = Restangular.all('authors');
Authors.post({
name: "J.R.R. Tolkien"
});
Say hi to Restangular
Lets’ create a new author:
var Authors = Restangular.all('authors');
Authors.post({
name: "J.R.R. Tolkien"
});
POST
http://api.rimoto.net/api/v1/authors/
Say hi to Restangular
Lets’ create a new author:
var Authors = Restangular.all('authors');
Authors.post({
name: "J.R.R. Tolkien"
});
Say hi to Restangular
Get the author:
Restangular.one('authors', 183).get()
.then(function(author) {
$scope.author = author;
})
;
Say hi to Restangular
Get the author:
Restangular.one('authors', 183).get()
.then(function(author) {
$scope.author = author;
})
;
GET
http://api.rimoto.net/api/v1/authors/183
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();
})
;
Pretty simple.. huh?
Model parsing
RestangularConfigurer.ExtendModel("books", function(book) {
book.published = new Date(book.published);
return book;
});
We can “transform” data from our API to javascript!
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>
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
Model function
But it’s an API function!
Model parsing
How can we solve that?
Model parsing
How can we solve that?
1. Create a transformer
2. Add the function to the model!
3. Fin.
Model parsing
How can we solve that?
1. Create a transformer
2. 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;
});
Model parsing
We can do use this tool for many cases:
1. Ordering lists
2. Special parsing
3. Add functions
4. Etc.
What about errors?
RestangularConfigurer.setErrorInterceptor(function(response) {
if([401, 403, 405].indexOf(response.status)!=-1) {
logout();
return false;
}
});
Build REST client like a
BOSS
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;
}])
;
PRO tips
1. You can set the `id` parameter (eg. for mongodb):
RestangularProvider.setRestangularFields({
id: '_id'
});
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
});
}
});
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'
});
Check it out
github.com/mgonto/restangular
Be creative,
and create your own API
Questions?
Thanks.

More Related Content

What's hot

Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API DocumentationSmartLogic
 
I18n
I18nI18n
I18nsoon
 
Python for AngularJS
Python for AngularJSPython for AngularJS
Python for AngularJSJeff Schenck
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsMatt Follett
 
Introduction to plugin development
Introduction to plugin developmentIntroduction to plugin development
Introduction to plugin developmentCaldera Labs
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockCaldera Labs
 
Build JSON and XML using RABL gem
Build JSON and XML using RABL gemBuild JSON and XML using RABL gem
Build JSON and XML using RABL gemNascenia IT
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Workhorse Computing
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.xRyan Szrama
 
2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with DreddRyan M Harrison
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017Jens Ravens
 
Developing on the aloashbei platform
Developing on the aloashbei platformDeveloping on the aloashbei platform
Developing on the aloashbei platformpycharmer
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hopeMarcus Ramberg
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientAdam Wiggins
 

What's hot (20)

Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API Documentation
 
Lies, Damn Lies, and Benchmarks
Lies, Damn Lies, and BenchmarksLies, Damn Lies, and Benchmarks
Lies, Damn Lies, and Benchmarks
 
I18n
I18nI18n
I18n
 
CBDW2014 - ColdBox RESTFul Services
CBDW2014 - ColdBox RESTFul ServicesCBDW2014 - ColdBox RESTFul Services
CBDW2014 - ColdBox RESTFul Services
 
Python for AngularJS
Python for AngularJSPython for AngularJS
Python for AngularJS
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right Reasons
 
Introduction to plugin development
Introduction to plugin developmentIntroduction to plugin development
Introduction to plugin development
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
 
Getting Started-with-Laravel
Getting Started-with-LaravelGetting Started-with-Laravel
Getting Started-with-Laravel
 
Build JSON and XML using RABL gem
Build JSON and XML using RABL gemBuild JSON and XML using RABL gem
Build JSON and XML using RABL gem
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.x
 
2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017
 
Developing on the aloashbei platform
Developing on the aloashbei platformDeveloping on the aloashbei platform
Developing on the aloashbei platform
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hope
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
 
Tornado
TornadoTornado
Tornado
 

Similar to Build REST API clients for AngularJS

Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Andres Almiray
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기RESTful API 제대로 만들기
RESTful API 제대로 만들기Juwon Kim
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyLaunchAny
 
PSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworksPSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworksElton Minetto
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)True-Vision
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with PerlDave Cross
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and PythonPiXeL16
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPressMarko Heijnen
 
Build a bot workshop async primer - php[tek]
Build a bot workshop  async primer - php[tek]Build a bot workshop  async primer - php[tek]
Build a bot workshop async primer - php[tek]Adam Englander
 
ZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async PrimerZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async PrimerAdam Englander
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
TPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and FluxTPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and FluxJirat Kijlerdpornpailoj
 
Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014samlown
 
Building and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CBuilding and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CDavid Wheeler
 

Similar to Build REST API clients for AngularJS (20)

Plack at YAPC::NA 2010
Plack at YAPC::NA 2010Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
 
Introduction to Retrofit
Introduction to RetrofitIntroduction to Retrofit
Introduction to Retrofit
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기RESTful API 제대로 만들기
RESTful API 제대로 만들기
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
 
PSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworksPSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworks
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPress
 
Build a bot workshop async primer - php[tek]
Build a bot workshop  async primer - php[tek]Build a bot workshop  async primer - php[tek]
Build a bot workshop async primer - php[tek]
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
ZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async PrimerZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async Primer
 
PSGI/Plack OSDC.TW
PSGI/Plack OSDC.TWPSGI/Plack OSDC.TW
PSGI/Plack OSDC.TW
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
TPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and FluxTPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and Flux
 
Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014
 
Building and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CBuilding and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning C
 

More from Almog Baku

Android is going to Go! Android and Golang
Android is going to Go! Android and GolangAndroid is going to Go! Android and Golang
Android is going to Go! Android and GolangAlmog Baku
 
Symfony2 form type
Symfony2 form typeSymfony2 form type
Symfony2 form typeAlmog Baku
 
Turbo theming: Introduction to Sass & Compass
Turbo theming: Introduction to Sass & CompassTurbo theming: Introduction to Sass & Compass
Turbo theming: Introduction to Sass & CompassAlmog Baku
 
Wordpress optimization
Wordpress optimizationWordpress optimization
Wordpress optimizationAlmog Baku
 
Drupal & javascript
Drupal & javascriptDrupal & javascript
Drupal & javascriptAlmog Baku
 

More from Almog Baku (6)

gRPC in Go
gRPC in GogRPC in Go
gRPC in Go
 
Android is going to Go! Android and Golang
Android is going to Go! Android and GolangAndroid is going to Go! Android and Golang
Android is going to Go! Android and Golang
 
Symfony2 form type
Symfony2 form typeSymfony2 form type
Symfony2 form type
 
Turbo theming: Introduction to Sass & Compass
Turbo theming: Introduction to Sass & CompassTurbo theming: Introduction to Sass & Compass
Turbo theming: Introduction to Sass & Compass
 
Wordpress optimization
Wordpress optimizationWordpress optimization
Wordpress optimization
 
Drupal & javascript
Drupal & javascriptDrupal & javascript
Drupal & javascript
 

Recently uploaded

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 

Recently uploaded (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 

Build REST API clients for AngularJS

  • 1. Build REST API client like a BOSS Build RESTful API clients for AngularJS, the proper way
  • 2. 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
  • 3. 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
  • 4. Disclaimer You wanna know more? Google it!
  • 5. What tha’ heck is REST? Representational State Transfer
  • 7. What is API? API is a layer that connects two applications. Application Programing Interface
  • 8. What is API? API is actually a common language, that both of the parties knows.
  • 9. REST REST is a Client-Server API
  • 10. REST REST is just the regular way the internet works! GET http://google.com/
  • 11. REST REST is just the regular way the internet works! GET http://google.com/RESPONSE 200 OK
  • 12. 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/:bookId 5. /api/authors/:authorId/books/:bookId/reviews 6. /api/authors/:authorId/books/:bookId/reviews/:reviewId
  • 13. 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/:bookId 5. /api/authors/:authorId/books/:bookId/reviews 6. /api/authors/:authorId/books/:bookId/reviews/:reviewId
  • 14. REST GET /api/authors/ [ { "id": 7, "name": "J.R.R. Tolkien", "birthday": "1-3-1892" }, { "id": 183, "name": "Douglas Adams", "birthday": "3-11-1952" } ]
  • 15. 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/:bookId 5. /api/authors/:authorId/books/:bookId/reviews 6. /api/authors/:authorId/books/:bookId/reviews/:reviewId
  • 16. REST GET /api/authors/187/ { "id": 183, "name": "J.R.R. Tolkien", "full_name": "John Ronald Reuel Tolkien", "birthday": "1-3-1892", "genre": "SciFi" }
  • 17. 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)
  • 18. REST Errors are simple http errors 200 - OK 404 - Not found 401 - Unauthorized 500 - Server Error Etc.
  • 19. REST REST is Stateless - You can’t use cookies - You need to pass your identification in every request GET /users/me?access_token=ftjhi89uh5982hbrvt92vgt9qvhg2r0219
  • 21. 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(); });
  • 22. The thing is… It just sucks
  • 23. 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(); });
  • 24. The thing is… It just sucks 2. Doesn’t allow you to parse the API 3. No way to set base url application wide 4. You can’t handle errors application wide 5. You can’t handle headers application wide 6. You can’t handle anything application wide Actually- $resource is okay for anything other than serious apps.
  • 25. 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(){...});
  • 26. 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');
  • 27. 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');
  • 28. 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');
  • 29. 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');
  • 30.
  • 32. 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
  • 33. 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'});
  • 34. Say hi to Restangular Let’s create a new author: var Authors = Restangular.all('authors'); Authors.post({ name: "J.R.R. Tolkien" });
  • 35. Say hi to Restangular Lets’ create a new author: var Authors = Restangular.all('authors'); Authors.post({ name: "J.R.R. Tolkien" }); POST http://api.rimoto.net/api/v1/authors/
  • 36. Say hi to Restangular Lets’ create a new author: var Authors = Restangular.all('authors'); Authors.post({ name: "J.R.R. Tolkien" });
  • 37. Say hi to Restangular Get the author: Restangular.one('authors', 183).get() .then(function(author) { $scope.author = author; }) ;
  • 38. Say hi to Restangular Get the author: Restangular.one('authors', 183).get() .then(function(author) { $scope.author = author; }) ; GET http://api.rimoto.net/api/v1/authors/183
  • 39. 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(); }) ;
  • 41. Model parsing RestangularConfigurer.ExtendModel("books", function(book) { book.published = new Date(book.published); return book; }); We can “transform” data from our API to javascript!
  • 42. 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>
  • 43. 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
  • 44. Model function But it’s an API function!
  • 45. Model parsing How can we solve that?
  • 46. Model parsing How can we solve that? 1. Create a transformer 2. Add the function to the model! 3. Fin.
  • 47. Model parsing How can we solve that? 1. Create a transformer 2. 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; });
  • 48. Model parsing We can do use this tool for many cases: 1. Ordering lists 2. Special parsing 3. Add functions 4. Etc.
  • 49. What about errors? RestangularConfigurer.setErrorInterceptor(function(response) { if([401, 403, 405].indexOf(response.status)!=-1) { logout(); return false; } });
  • 50. Build REST client like a BOSS
  • 51. 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; }]) ;
  • 52. PRO tips 1. You can set the `id` parameter (eg. for mongodb): RestangularProvider.setRestangularFields({ id: '_id' });
  • 53. 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 }); } });
  • 54. 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' });
  • 56. Be creative, and create your own API