SlideShare a Scribd company logo
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');
Build REST API clients for AngularJS
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.
Ad

Recommended

Build REST APIs like a Jedi with Symfony2
Build REST APIs like a Jedi with Symfony2
Almog Baku
 
Consume RESTful APIs with $resource and Restangular
Consume RESTful APIs with $resource and Restangular
John Schmidt
 
REST in AngularJS
REST in AngularJS
a_sharif
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
vvaswani
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW Workshop
CalderaLearn
 
RSpec 2 Best practices
RSpec 2 Best practices
Andrea Reginato
 
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
Caldera Labs
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
Yusuke Wada
 
Rspec API Documentation
Rspec API Documentation
SmartLogic
 
Lies, Damn Lies, and Benchmarks
Lies, Damn Lies, and Benchmarks
Workhorse Computing
 
I18n
I18n
soon
 
CBDW2014 - ColdBox RESTFul Services
CBDW2014 - ColdBox RESTFul Services
Ortus Solutions, Corp
 
Python for AngularJS
Python for AngularJS
Jeff Schenck
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right Reasons
Matt Follett
 
Introduction to plugin development
Introduction to plugin development
Caldera Labs
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
Caldera Labs
 
Getting Started-with-Laravel
Getting Started-with-Laravel
Mindfire Solutions
 
Build JSON and XML using RABL gem
Build JSON and XML using RABL gem
Nascenia IT
 
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.x
Ryan Szrama
 
2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd
Ryan M Harrison
 
Modern Perl
Modern Perl
Dave Cross
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017
Jens Ravens
 
Developing on the aloashbei platform
Developing on the aloashbei platform
pycharmer
 
Mojolicious - A new hope
Mojolicious - A new hope
Marcus Ramberg
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
Adam Wiggins
 
Tornado
Tornado
Cristian Andreica
 
Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
Tatsuhiko Miyagawa
 
Introduction to Retrofit
Introduction to Retrofit
Kazuhiro Serizawa
 

More Related Content

What's hot (20)

Rspec API Documentation
Rspec API Documentation
SmartLogic
 
Lies, Damn Lies, and Benchmarks
Lies, Damn Lies, and Benchmarks
Workhorse Computing
 
I18n
I18n
soon
 
CBDW2014 - ColdBox RESTFul Services
CBDW2014 - ColdBox RESTFul Services
Ortus Solutions, Corp
 
Python for AngularJS
Python for AngularJS
Jeff Schenck
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right Reasons
Matt Follett
 
Introduction to plugin development
Introduction to plugin development
Caldera Labs
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
Caldera Labs
 
Getting Started-with-Laravel
Getting Started-with-Laravel
Mindfire Solutions
 
Build JSON and XML using RABL gem
Build JSON and XML using RABL gem
Nascenia IT
 
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.x
Ryan Szrama
 
2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd
Ryan M Harrison
 
Modern Perl
Modern Perl
Dave Cross
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017
Jens Ravens
 
Developing on the aloashbei platform
Developing on the aloashbei platform
pycharmer
 
Mojolicious - A new hope
Mojolicious - A new hope
Marcus Ramberg
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
Adam Wiggins
 
Tornado
Tornado
Cristian Andreica
 
Rspec API Documentation
Rspec API Documentation
SmartLogic
 
I18n
I18n
soon
 
Python for AngularJS
Python for AngularJS
Jeff Schenck
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right Reasons
Matt Follett
 
Introduction to plugin development
Introduction to plugin development
Caldera Labs
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
Caldera Labs
 
Build JSON and XML using RABL gem
Build JSON and XML using RABL gem
Nascenia IT
 
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.x
Ryan Szrama
 
2019-08-23 API contract testing with Dredd
2019-08-23 API contract testing with Dredd
Ryan M Harrison
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017
Jens Ravens
 
Developing on the aloashbei platform
Developing on the aloashbei platform
pycharmer
 
Mojolicious - A new hope
Mojolicious - A new hope
Marcus Ramberg
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
Adam Wiggins
 

Similar to Build REST API clients for AngularJS (20)

Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
Tatsuhiko Miyagawa
 
Introduction to Retrofit
Introduction to Retrofit
Kazuhiro Serizawa
 
JSON and the APInauts
JSON and the APInauts
Wynn Netherland
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
Andres Almiray
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기
Juwon Kim
 
API Platform: The Pragmatic API framework
API Platform: The Pragmatic API framework
soyuka1
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
LaunchAny
 
PSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworks
Elton Minetto
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
True-Vision
 
Modern Web Development with Perl
Modern Web Development with Perl
Dave Cross
 
REST with Eve and Python
REST with Eve and Python
PiXeL16
 
Creating native apps with WordPress
Creating native apps with WordPress
Marko Heijnen
 
Build a bot workshop async primer - php[tek]
Build a bot workshop async primer - php[tek]
Adam Englander
 
Intro to PSGI and Plack
Intro to PSGI and Plack
Tatsuhiko Miyagawa
 
Rack Middleware
Rack Middleware
LittleBIGRuby
 
ZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async Primer
Adam Englander
 
PSGI/Plack OSDC.TW
PSGI/Plack OSDC.TW
Tatsuhiko Miyagawa
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 
TPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and Flux
Jirat Kijlerdpornpailoj
 
Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014
samlown
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
Andres Almiray
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기
Juwon Kim
 
API Platform: The Pragmatic API framework
API Platform: The Pragmatic API framework
soyuka1
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
LaunchAny
 
PSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworks
Elton Minetto
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
True-Vision
 
Modern Web Development with Perl
Modern Web Development with Perl
Dave Cross
 
REST with Eve and Python
REST with Eve and Python
PiXeL16
 
Creating native apps with WordPress
Creating native apps with WordPress
Marko Heijnen
 
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 Primer
Adam Englander
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 
TPSE Thailand 2015 - Rethinking Web with React and Flux
TPSE Thailand 2015 - Rethinking Web with React and Flux
Jirat Kijlerdpornpailoj
 
Finding Restfulness - Madrid.rb April 2014
Finding Restfulness - Madrid.rb April 2014
samlown
 
Ad

More from Almog Baku (6)

gRPC in Go
gRPC in Go
Almog Baku
 
Android is going to Go! Android and Golang
Android is going to Go! Android and Golang
Almog Baku
 
Symfony2 form type
Symfony2 form type
Almog Baku
 
Turbo theming: Introduction to Sass & Compass
Turbo theming: Introduction to Sass & Compass
Almog Baku
 
Wordpress optimization
Wordpress optimization
Almog Baku
 
Drupal & javascript
Drupal & javascript
Almog Baku
 
Android is going to Go! Android and Golang
Android is going to Go! Android and Golang
Almog Baku
 
Symfony2 form type
Symfony2 form type
Almog Baku
 
Turbo theming: Introduction to Sass & Compass
Turbo theming: Introduction to Sass & Compass
Almog Baku
 
Wordpress optimization
Wordpress optimization
Almog Baku
 
Drupal & javascript
Drupal & javascript
Almog Baku
 
Ad

Recently uploaded (20)

Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
 
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
Safe Software
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
revolcs10
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
The Future of Technology: 2025-2125 by Saikat Basu.pdf
The Future of Technology: 2025-2125 by Saikat Basu.pdf
Saikat Basu
 
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
janeliewang985
 
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Josef Weingand
 
You are not excused! How to avoid security blind spots on the way to production
You are not excused! How to avoid security blind spots on the way to production
Michele Leroux Bustamante
 
PyCon SG 25 - Firecracker Made Easy with Python.pdf
PyCon SG 25 - Firecracker Made Easy with Python.pdf
Muhammad Yuga Nugraha
 
Mastering AI Workflows with FME by Mark Döring
Mastering AI Workflows with FME by Mark Döring
Safe Software
 
Curietech AI in action - Accelerate MuleSoft development
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
 
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
Safe Software
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
revolcs10
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
The Future of Technology: 2025-2125 by Saikat Basu.pdf
The Future of Technology: 2025-2125 by Saikat Basu.pdf
Saikat Basu
 
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
janeliewang985
 
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Josef Weingand
 
You are not excused! How to avoid security blind spots on the way to production
You are not excused! How to avoid security blind spots on the way to production
Michele Leroux Bustamante
 
PyCon SG 25 - Firecracker Made Easy with Python.pdf
PyCon SG 25 - Firecracker Made Easy with Python.pdf
Muhammad Yuga Nugraha
 
Mastering AI Workflows with FME by Mark Döring
Mastering AI Workflows with FME by Mark Döring
Safe Software
 
Curietech AI in action - Accelerate MuleSoft development
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 

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');
  • 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