SlideShare una empresa de Scribd logo
1 de 73
Descargar para leer sin conexión
Talking Heads 
REST api’s don’t need to be your “psycho-killer”
Dancer 2 
A Lightweight WEB Framework 
… that does nothing wrong
Dancer 2 
A Lightweight WEB Framework 
… that does nothing you don’t want
Dancer 2 
A Lightweight WEB Framework 
… does it do what it should do?
RESTful API’s 
Dancer 2 
HTTP protocols and RFC’s
Overview 
• HTTP 1.1 Protocol 
• Let’s Dance 
• Caching 
• Conditional Requests 
• Content Negotiation 
• Authorization
HTTP/1.1 Protocol 
• Requests 
• Responses 
• Request Methods 
• Header Fields 
• Status codes
HTTP 1.1 Protocol 
Request 
GET /some_resource HTTP/1.1 
Host: server.tst 
User-Agent: insane_client/0.1 
Accept: text/html; q=0.8, image/gif; q=0.3 
Accept-Charset: iso8509-1 
Content-Length: 123 
Here can come some content, for what ever 
purpose
HTTP 1.1 Protocol 
Request 
GET /some_resource HTTP/1.1 
Host: server.tst 
User-Agent: insane_client/0.1 
Accept: text/html; q=0.8, image/gif; q=0.3 
Accept-Charset: iso8509-1 
Content-Length: 123 
Here can come some content, for what ever 
purpose
HTTP 1.1 Protocol 
Request 
GET /some_resource HTTP/1.1 
Host: server.tst 
User-Agent: insane_client/0.1 
Accept: text/html; q=0.8, image/gif; q=0.3 
Accept-Charset: iso8509-1 
Content-Length: 123 
Here can come some content, for what ever 
purpose
HTTP 1.1 Protocol 
Request 
GET /some_resource HTTP/1.1 
Host: server.tst 
User-Agent: insane_client/0.1 
Accept: text/html; q=0.8, image/gif; q=0.3 
Accept-Charset: iso8509-1 
Content-Length: 123 
Here can come some content, for what ever 
purpose
HTTP 1.1 Protocol 
Request 
GET /some_resource HTTP/1.1 
Host: server.tst 
User-Agent: insane_client/0.1 
Accept: text/html; q=0.8, image/gif; q=0.3 
Accept-Charset: iso8509-1 
Content-Length: 123 
Here can come some content, for what ever 
purpose
HTTP 1.1 Protocol 
Response 
HTTP/1.1 200 OK 
Server: dancer/2.0 
Date: Tue, 14 Oct 2014 12:34:56 GMT 
Content-Type: text/plain 
Charset: iso8509-1 
Content-Length: 456 
You asked for something, here it is!
HTTP 1.1 Protocol 
Response 
HTTP/1.1 200 OK 
Server: dancer/2.0 
Date: Tue, 14 Oct 2014 12:34:56 GMT 
Content-Type: text/plain 
Charset: iso8509-1 
Content-Length: 456 
You asked for something, here it is!
HTTP 1.1 Protocol 
Response 
HTTP/1.1 200 OK 
Server: dancer/2.0 
Date: Tue, 14 Oct 2014 12:34:56 GMT 
Content-Type: text/plain 
Charset: iso8509-1 
Content-Length: 456 
You asked for something, here it is!
HTTP 1.1 Protocol 
Response 
HTTP/1.1 200 OK 
Server: dancer/2.0 
Date: Tue, 14 Oct 2014 12:34:56 GMT 
Content-Type: text/plain 
Charset: iso8509-1 
Content-Length: 456 
You asked for something, here it is!
HTTP 1.1 Protocol 
Response 
HTTP/1.1 200 OK 
Server: dancer/2.0 
Date: Tue, 14 Oct 2014 12:34:56 GMT 
Content-Type: text/plain 
Charset: iso8509-1 
Content-Length: 456 
You asked for something, here it is!
HTTP 1.1 Protocol 
Request Methodes 
• GET 
• POST 
• PUT 
• DELETE 
• HEAD 
• OPTIONS 
• PATCH
HTTP 1.1 Protocol 
Header Fields 
• Host 
• User-Agent 
• If-Modified-Since 
• Content-Type 
• Content-Length 
• Location 
• Server 
• Last-Modification 
• Content-Type 
• Content-Length
HTTP 1.1 Protocol 
Status Codes 
• 1—— Informational 
• 2—— Succes 
• 3—— Redirection 
• 4—— Client Error 
• 5—— Server
Status: 404 
Not Found
Status: 404 
Not Found
Status: 500 
Internal Server Error
HTTP 1.1 Protocol 
Status 1—— Informational 
• 100 Continue
HTTP 1.1 Protocol 
Status 2—— Succes 
• 200 OK 
• 201 Created 
• 202 Accepted 
• 204 No Content
HTTP 1.1 Protocol 
Status 3—— Redirection 
• 300 Multiple Choices 
• 301 Moved Permanently 
• 304 Not Modified
HTTP 1.1 Protocol 
Status 4—— Client Error 
• 400 Bad Request 
• 401 Unauthorized 
• 403 Forbidden 
• 404 Not Found 
• 405 Method Not Allowed 
• 407 Not Acceptable 
• 410 Gone 
• 412 Precondition Failed
HTTP 1.1 Protocol 
Status 5—— Server Error 
• 500 Internal Server Error 
• 501 Not Implemented 
• 503 Service Unavailable
It takes Two 
Dancer 2 & LWP
Client Server 
Let’s Dance 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)- 
>find(id=>params(’id’)); 
template ’user.tt’, $user_info; 
}; 
dance; 
1;
Client Server 
Let’s Dance 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)- 
>find(id=>params(’id’)); 
template ’user.tt’, $user_info; 
}; 
dance; 
1;
Client Server 
Let’s Dance 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)- 
>find(id=>params(’id’)); 
template ’user.tt’, $user_info; 
}; 
dance; 
1;
Client Server 
Let’s Dance 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)- 
>find(id=>params(’id’)); 
template ’user.tt’, $user_info; 
}; 
dance; 
1;
Client Server 
Let’s Dance 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)- 
>find(id=>params(’id’)); 
template ’user.tt’, $user_info; 
}; 
dance; 
1;
Client Server 
Let’s Dance 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)- 
>find(id=>params(’id’)); 
template ’user.tt’, $user_info; 
}; 
dance; 
1;
Client Server 
LWP::UserAgent 
use LWP; 
use LWP::UserAgent; 
my $agent = LWP::UserAgent->new; 
my $response = $agent->get(’/user/999-999’);
Caching 
Temporary Storage 
• Reduce cost 
• Improve Responsivness
Caching 
Temporary Storage 
• Client Side 
• Public Proxy 
• Server Side
Caching 
If-Modified-Since 
use LWP; 
use LWP::UserAgent; 
my $agent = LWP::UserAgent->new; 
my $request = HTTP::Request->new( 
GET => ’/user/999-999-999’); 
$request->header( 
If-Modified-Since => Tue, 14 Oct 2014 12:34:56 
GMT ); 
my $response = $agent->request($request);
Caching 
Response 
• Response Status: 304 Not Modified 
• Last-Modified: Tue, 07 Oct 2014 12:34:56 GMT 
• Age: 3600 
• Expire: Tue, 21 Oct 2014 12:34:56 GMT 
• Cache-Control: public | private | max-age | no-cache
Conditional Requests 
• Stateless 
• No Resource Locking 
• Only execute request if not modified since 
last 
• Only execute request if the resource is still 
the same
Conditional Requests 
If-Unmodified-Since 
use LWP; 
use LWP::UserAgent; 
my $agent = LWP::UserAgent->new; 
my $request = HTTP::Request->new( 
DELETE => ’/user/999-999-999’); 
$request->header( 
If-Unmodified-Since => ’Tue, 14 Oct 2014 
12:34:56 GMT’); 
my $response = $agent->request($request);
Conditional Requests 
If-Match 
use LWP; 
use LWP::UserAgent; 
my $agent = LWP::UserAgent->new; 
my $request = HTTP::Request->new( 
DELETE => ’/user/999-999-999’); 
$request->header( 
If-Match => 
’a23dfe4532dab7b21a83d3e0f4c2a6f1’ ); 
my $response = $agent->request($request);
Conditional Requests 
Response 
• Response Status: 412 Precondition Failed 
• Response Status: 428 Precondition Required 
• Last-Modified: Tue, 07 Oct 2014 12:34:56 GMT 
• ETag: a23dfe4532dab7b21a83d3e0f4c2a6f1
Content Negotiation 
• the same resource 
• another representation 
• the same URL 
• client can let the server know what type is preferred 
• server will try to deliver in requested content 
• caches need to know that this is another variant 
• the same URL
Content Negotiation 
Resources & Representation 
• Uniform Resouse Identifier 
• Does not say anything about representation: 
• Charset 
• Encoding 
• Language 
• Format
Content Negotiation 
Accept & friends 
• Accept: text/html, text/plain, image/png 
• Accept-Language: nl, en, fr 
• Accept-Charset: iso_ 
• Accept-Encoding: gzip
Content Negotiation 
Accepting Preferences 
• The client can have some nice preferences 
• it might like some representation above the other 
• it might not like anything else 
• The server can only deliver some representations 
• it might deliver something it prefers 
• it might give a list of options
Content Negotiation 
Mutable Serializer 
use Dancer2; 
use Dancer2::Plugin::Mutable::Serializer; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)- 
>find(id=>params(’id’)); 
return $user_info; 
}; 
1;
Content Negotiation 
Mutable Serializer 
use LWP; 
use LWP::UserAgent; 
my $agent = LWP::UserAgent->new; 
my $request = HTTP::Request->new( 
GET => ’/user/999-999-999’); 
$request->header( 
Accept => ’application/json’ ); 
my $response = $agent->request($request);
Content Negotiation 
Mutable Serializer 
use LWP; 
use LWP::UserAgent; 
my $agent = LWP::UserAgent->new; 
my $request = HTTP::Request->new( 
GET => ’/user/999-999-999’); 
$request->header( 
Accept => ’application/json’ ); 
$request->header( 
Content-Type => ’application/xml’ ); 
my $response = $agent->request($request);
Content Negotiation 
Let’s do things differently 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)->find(id=>params(’id’)); 
if (grep $_ eq ’text/html’, header(’Accept’)) { 
template ’user.tt’, $user_info; } 
if (grep $_ eq ’application/json’, header(’Accept’’)) { 
return to_json $user_info; } 
if (grep $_ eq ’application/xml’, header(’Accept’’)) { 
return to_xml $user_info; } 
}; 
1;
Content Negotiation 
Let’s do things differently 
use LWP; 
use LWP::UserAgent; 
my $agent = LWP::UserAgent->new; 
my $request = HTTP::Request->new( 
GET => ’/user/999-999-999’); 
$request->header( 
Accept => ’application/json’ ); 
my $response = $agent->request($request);
Content Negotiation 
Let’s do things differently 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)->find(id=>params(’id’)); 
if (grep $_ eq ’text/html’, header(’Accept’)) { 
template ’user.tt’, $user_info; } 
if (grep $_ eq ’application/json’, header(’Accept’’)) { 
return to_json $user_info; } 
if (grep $_ eq ’application/xml’, header(’Accept’’)) { 
return to_xml $user_info; } 
}; 
1;
Content Negotiation 
Let’s do things differently 
use LWP; 
use LWP::UserAgent; 
my $agent = LWP::UserAgent->new; 
my $request = HTTP::Request->new( 
GET => ’/user/999-999-999’); 
$request->header( 
Accept => ’application/xml; q=0.1, text/html’ ); 
my $response = $agent->request($request);
Content Negotiation 
Let’s do things differently 
use Dancer2; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)->find(id=>params(’id’)); 
if (grep $_ eq ’text/html’, header(’Accept’)) { 
template ’user.tt’, $user_info; } 
if (grep $_ eq ’application/json’, header(’Accept’’)) { 
return to_json $user_info; } 
if (grep $_ eq ’application/xml’, header(’Accept’’)) { 
return to_xml $user_info; } 
}; 
1;
Content Negotiation 
Let’s get Messy 
Accept: text/plain; q=0.3, text/html; q=0.5, */*; q=0.0 
text/plain 
q=0.3 
text/html 
q=0.5 
*/* 
q=0.0 
«I’m fine with plain-txt, but like html more… but 
if it’s anything else, I DON’T WANT THAT»
Content Negotiation 
Let’s get Messy 
use Dancer2; 
use Dancer2::Plugin::HTTP::ContentNegotiation; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)->find(id=>params(’id’)); 
http_choose_accept ( 
’text/html’ 
=> sub {template ’user.tt’, $user_info}, 
’application/json’ 
=> sub {to_json $user_info}, 
’application/xml’ 
=> sub {to_xml $user_info}, 
); 
};
Content Negotiation 
Let’s get Messy 
use Dancer2; 
use Dancer2::Plugin::HTTP::ContentNegotiation; 
get ’/user/:id’ => { 
my $user_info 
= resultset(’users’)- 
>find(id=>params(’id’)); 
http_choose_accept ( 
[’image/png’, ’image/jpg’, ’image/gif’] 
=> sub {magick(http_accept->minor)}, 
); 
};
Content Negotiation 
Resources & Representation 
• Status 300: Multiple Choices 
• format at the end of the URL 
• language at the beginning of the URL 
• Status 406: Not Acceptable 
• Vary: Accept, Aceept-Language . . .
Auth 
Resource Access 
• Stateless 
• Submit credentials with every request 
• Authentication 
• Username & Password 
• Authentication Scheme 
• Authorisation 
• Rolebased access
Auth 
Usual WEB handling 
1. Attempt to acces some page 
2. Not Authorised ? 
3. Go to /login 
4. Send credentials 
5. Authenticated Now ? 
6. Setup session cookie 
7. Go back to original requested page
Auth 
REST api 
1. Attempt to acces some page 
2. Not Authenticated ? 
3. Status: 401 “Not Authorized” 
4. Resend same request including credentials 
5. Authorised ? 
• Continue processing 
• Status: 403 “Forbidden”
Auth 
HTTP Auth::Extensible 
use Dancer2; 
use Dancer2::Plugin::HTTP::Auth::Extensible; 
get '/realm' => http_require_authentication sub { 
"You are logged in using realm: " . http_realm 
}; 
get '/vodka' => http_require_role HardDrinker => 
sub { 
"Only hard drinkers get vodka"; 
};
Auth 
HTTP Auth::Extensible 
use Dancer2; 
use Dancer2::Plugin::HTTP::Auth::Extensible; 
get '/realm' => http_require_authentication sub { 
"You are logged in using realm: " . http_realm 
}; 
get '/vodka' => http_require_role HardDrinker => 
sub { 
"Only hard drinkers get vodka"; 
};
Auth 
HTTP Auth::Extensible 
use Dancer2; 
use Dancer2::Plugin::HTTP::Auth::Extensible; 
get '/realm' => http_require_authentication sub { 
"You are logged in using realm: " . http_realm 
}; 
get '/vodka' => http_require_role HardDrinker => 
sub { 
"Only hard drinkers get vodka"; 
};
Auth 
HTTP Auth::Extensible 
plugins: 
'HTTP::Auth::Extensible': 
realms: 
example: 
provider: Config 
users: 
- user: ‘beerdrinker' 
pass: ‘password' 
name: 'Beer drinker’ 
roles: 
- BeerDrinker
Auth 
Resource Access 
• Status 401: Unauthorized 
• You should return a WWW-Authenticate 
also 
• HTTP Request Header Field: Authorize 
• Status 403: Forbidden
Dancer2::Plugin::HTTP 
Family 
• Dancer2::Plugin::HTTP::ContentNegotiation 
• Dancer2::Plugin::HTTP::Auth::Extensible 
• Dancer2::Plugin::HTTP::Conditional 
• Dancer2::Plugin::HTTP::Cache
Dancer2::Plugin::HTTP 
HTTP::Header::ActionPack 
• Authentication / Authorisation 
• MIME-types 
• DateTime conversion
Dancer2::Plugin::HTTP 
HTTP::Header::ActionPack 
• Authentication / Authorisation 
• MIME-types 
• DateTime conversion
Net::WebMachine 
HTTP::Header::ActionPack 
• Basho schema 
• Ruby implementation 
• Stevan Little / Dave Rolsky
Talking Heads 
http://github/THEMA-MEDIA/ 
th.J.v.Hoesel@THEMA-MEDIA.nl

Más contenido relacionado

La actualidad más candente

HTTP and Your Angry Dog
HTTP and Your Angry DogHTTP and Your Angry Dog
HTTP and Your Angry DogRoss Tuck
 
4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebookguoqing75
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webclkao
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and PythonPiXeL16
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Masahiro Nagano
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with PerlDave Cross
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015Fernando Hamasaki de Amorim
 
Perl in the Internet of Things
Perl in the Internet of ThingsPerl in the Internet of Things
Perl in the Internet of ThingsDave Cross
 
Eve - REST API for Humans™
Eve - REST API for Humans™Eve - REST API for Humans™
Eve - REST API for Humans™Nicola Iarocci
 
Java web programming
Java web programmingJava web programming
Java web programmingChing Yi Chan
 
DBD::Gofer 200809
DBD::Gofer 200809DBD::Gofer 200809
DBD::Gofer 200809Tim Bunce
 
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...Codemotion
 
Drinking from the Elixir Fountain of Resilience
Drinking from the Elixir Fountain of ResilienceDrinking from the Elixir Fountain of Resilience
Drinking from the Elixir Fountain of ResilienceC4Media
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
MongoDB World 2019: Exploring your MongoDB Data with Pirates (R) and Snakes (...
MongoDB World 2019: Exploring your MongoDB Data with Pirates (R) and Snakes (...MongoDB World 2019: Exploring your MongoDB Data with Pirates (R) and Snakes (...
MongoDB World 2019: Exploring your MongoDB Data with Pirates (R) and Snakes (...MongoDB
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 

La actualidad más candente (20)

HTTP and Your Angry Dog
HTTP and Your Angry DogHTTP and Your Angry Dog
HTTP and Your Angry Dog
 
4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
Follow the White Rabbit - Message Queues with PHP
Follow the White Rabbit - Message Queues with PHPFollow the White Rabbit - Message Queues with PHP
Follow the White Rabbit - Message Queues with PHP
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
 
NLTK in 20 minutes
NLTK in 20 minutesNLTK in 20 minutes
NLTK in 20 minutes
 
Perl in the Internet of Things
Perl in the Internet of ThingsPerl in the Internet of Things
Perl in the Internet of Things
 
Eve - REST API for Humans™
Eve - REST API for Humans™Eve - REST API for Humans™
Eve - REST API for Humans™
 
Java web programming
Java web programmingJava web programming
Java web programming
 
DBD::Gofer 200809
DBD::Gofer 200809DBD::Gofer 200809
DBD::Gofer 200809
 
Text analysis using python
Text analysis using pythonText analysis using python
Text analysis using python
 
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
 
Beyond Phoenix
Beyond PhoenixBeyond Phoenix
Beyond Phoenix
 
Drinking from the Elixir Fountain of Resilience
Drinking from the Elixir Fountain of ResilienceDrinking from the Elixir Fountain of Resilience
Drinking from the Elixir Fountain of Resilience
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
MongoDB World 2019: Exploring your MongoDB Data with Pirates (R) and Snakes (...
MongoDB World 2019: Exploring your MongoDB Data with Pirates (R) and Snakes (...MongoDB World 2019: Exploring your MongoDB Data with Pirates (R) and Snakes (...
MongoDB World 2019: Exploring your MongoDB Data with Pirates (R) and Snakes (...
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 

Destacado

National Preparedness System (NPS) component: TractorFax ppt information acti...
National Preparedness System (NPS) component: TractorFax ppt information acti...National Preparedness System (NPS) component: TractorFax ppt information acti...
National Preparedness System (NPS) component: TractorFax ppt information acti...JD Hamilton
 
Seafield Resources Ltd. - Corporate Presentation - April, 2012
Seafield Resources Ltd. - Corporate Presentation - April, 2012Seafield Resources Ltd. - Corporate Presentation - April, 2012
Seafield Resources Ltd. - Corporate Presentation - April, 2012sffresources
 
About TractorFax: Created, perfected, & confimred in supporting the NPS
About TractorFax: Created, perfected, & confimred in supporting the NPSAbout TractorFax: Created, perfected, & confimred in supporting the NPS
About TractorFax: Created, perfected, & confimred in supporting the NPSJD Hamilton
 
Application Holy Wars theme and why the book was written
Application Holy Wars theme and why the book was writtenApplication Holy Wars theme and why the book was written
Application Holy Wars theme and why the book was writtenWilliam Hall
 
Episode 5(3): Where and how we started our path to now - Meetup session 18
Episode 5(3): Where and how we started our path to now - Meetup session 18Episode 5(3): Where and how we started our path to now - Meetup session 18
Episode 5(3): Where and how we started our path to now - Meetup session 18William Hall
 
Run united 1 bloggers night presentation
Run united 1 bloggers night presentationRun united 1 bloggers night presentation
Run united 1 bloggers night presentationUlikblogRunner
 
Hall brouwers2004tenixmatrixinovsummitcmis(present)
Hall brouwers2004tenixmatrixinovsummitcmis(present)Hall brouwers2004tenixmatrixinovsummitcmis(present)
Hall brouwers2004tenixmatrixinovsummitcmis(present)William Hall
 
Soil experiment
Soil experimentSoil experiment
Soil experimentnewham5-6
 
Tp7 akavent systems principles(dr)
Tp7 akavent systems principles(dr)Tp7 akavent systems principles(dr)
Tp7 akavent systems principles(dr)Marc Buitenhuis
 
TOP500 List November 2014
TOP500 List November 2014TOP500 List November 2014
TOP500 List November 2014top500
 
A Glassof Milk.Pps
A Glassof Milk.PpsA Glassof Milk.Pps
A Glassof Milk.Ppsvinod kumar
 
Hall, W.P. 2006. Emergence and growth of knowledge and diversity in hierarchi...
Hall, W.P. 2006. Emergence and growth of knowledge and diversity in hierarchi...Hall, W.P. 2006. Emergence and growth of knowledge and diversity in hierarchi...
Hall, W.P. 2006. Emergence and growth of knowledge and diversity in hierarchi...William Hall
 
Magic 8 Ball pc
Magic 8 Ball pcMagic 8 Ball pc
Magic 8 Ball pcKal Hack
 
When Should You Retain a Forensic Accountant?
When Should You Retain a Forensic Accountant?When Should You Retain a Forensic Accountant?
When Should You Retain a Forensic Accountant?Jeff Moore
 

Destacado (20)

National Preparedness System (NPS) component: TractorFax ppt information acti...
National Preparedness System (NPS) component: TractorFax ppt information acti...National Preparedness System (NPS) component: TractorFax ppt information acti...
National Preparedness System (NPS) component: TractorFax ppt information acti...
 
Seafield Resources Ltd. - Corporate Presentation - April, 2012
Seafield Resources Ltd. - Corporate Presentation - April, 2012Seafield Resources Ltd. - Corporate Presentation - April, 2012
Seafield Resources Ltd. - Corporate Presentation - April, 2012
 
About TractorFax: Created, perfected, & confimred in supporting the NPS
About TractorFax: Created, perfected, & confimred in supporting the NPSAbout TractorFax: Created, perfected, & confimred in supporting the NPS
About TractorFax: Created, perfected, & confimred in supporting the NPS
 
Application Holy Wars theme and why the book was written
Application Holy Wars theme and why the book was writtenApplication Holy Wars theme and why the book was written
Application Holy Wars theme and why the book was written
 
Episode 5(3): Where and how we started our path to now - Meetup session 18
Episode 5(3): Where and how we started our path to now - Meetup session 18Episode 5(3): Where and how we started our path to now - Meetup session 18
Episode 5(3): Where and how we started our path to now - Meetup session 18
 
Run united 1 bloggers night presentation
Run united 1 bloggers night presentationRun united 1 bloggers night presentation
Run united 1 bloggers night presentation
 
E nterpellami
E nterpellamiE nterpellami
E nterpellami
 
Hall brouwers2004tenixmatrixinovsummitcmis(present)
Hall brouwers2004tenixmatrixinovsummitcmis(present)Hall brouwers2004tenixmatrixinovsummitcmis(present)
Hall brouwers2004tenixmatrixinovsummitcmis(present)
 
Presentation fc nov
Presentation fc novPresentation fc nov
Presentation fc nov
 
Soil experiment
Soil experimentSoil experiment
Soil experiment
 
Leerkrassistent Pennenstreken
Leerkrassistent PennenstrekenLeerkrassistent Pennenstreken
Leerkrassistent Pennenstreken
 
Keynote Mobile
Keynote MobileKeynote Mobile
Keynote Mobile
 
Tp7 akavent systems principles(dr)
Tp7 akavent systems principles(dr)Tp7 akavent systems principles(dr)
Tp7 akavent systems principles(dr)
 
TOP500 List November 2014
TOP500 List November 2014TOP500 List November 2014
TOP500 List November 2014
 
Resume
ResumeResume
Resume
 
A Glassof Milk.Pps
A Glassof Milk.PpsA Glassof Milk.Pps
A Glassof Milk.Pps
 
Hall, W.P. 2006. Emergence and growth of knowledge and diversity in hierarchi...
Hall, W.P. 2006. Emergence and growth of knowledge and diversity in hierarchi...Hall, W.P. 2006. Emergence and growth of knowledge and diversity in hierarchi...
Hall, W.P. 2006. Emergence and growth of knowledge and diversity in hierarchi...
 
Magic 8 Ball pc
Magic 8 Ball pcMagic 8 Ball pc
Magic 8 Ball pc
 
Bussiness plan
Bussiness planBussiness plan
Bussiness plan
 
When Should You Retain a Forensic Accountant?
When Should You Retain a Forensic Accountant?When Should You Retain a Forensic Accountant?
When Should You Retain a Forensic Accountant?
 

Similar a Talking Heads - writing an API does not need to be a "psycho killer"

Making the Most of HTTP In Your Apps
Making the Most of HTTP In Your AppsMaking the Most of HTTP In Your Apps
Making the Most of HTTP In Your AppsBen Ramsey
 
Web II - 02 - How ASP.NET Works
Web II - 02 - How ASP.NET WorksWeb II - 02 - How ASP.NET Works
Web II - 02 - How ASP.NET WorksRandy Connolly
 
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
 
Designing a RESTful web service
Designing a RESTful web serviceDesigning a RESTful web service
Designing a RESTful web serviceFilip Blondeel
 
HTTP fundamentals for developers
HTTP fundamentals for developersHTTP fundamentals for developers
HTTP fundamentals for developersMario Cardinal
 
OAuth 2.0 and Library
OAuth 2.0 and LibraryOAuth 2.0 and Library
OAuth 2.0 and LibraryKenji Otsuka
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server Masahiro Nagano
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsCarol McDonald
 
Design Web Service API by HungerStation
Design Web Service API by HungerStationDesign Web Service API by HungerStation
Design Web Service API by HungerStationArabNet ME
 
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Codemotion
 
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Codemotion
 
Services web RESTful
Services web RESTfulServices web RESTful
Services web RESTfulgoldoraf
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...Tom Croucher
 

Similar a Talking Heads - writing an API does not need to be a "psycho killer" (20)

Making the Most of HTTP In Your Apps
Making the Most of HTTP In Your AppsMaking the Most of HTTP In Your Apps
Making the Most of HTTP In Your Apps
 
Web services tutorial
Web services tutorialWeb services tutorial
Web services tutorial
 
Web Services Tutorial
Web Services TutorialWeb Services Tutorial
Web Services Tutorial
 
Http and security
Http and securityHttp and security
Http and security
 
Web II - 02 - How ASP.NET Works
Web II - 02 - How ASP.NET WorksWeb II - 02 - How ASP.NET Works
Web II - 02 - How ASP.NET Works
 
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.
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
Designing a RESTful web service
Designing a RESTful web serviceDesigning a RESTful web service
Designing a RESTful web service
 
HTTP fundamentals for developers
HTTP fundamentals for developersHTTP fundamentals for developers
HTTP fundamentals for developers
 
OAuth 2.0 and Library
OAuth 2.0 and LibraryOAuth 2.0 and Library
OAuth 2.0 and Library
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
 
Rest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.jsRest with Java EE 6 , Security , Backbone.js
Rest with Java EE 6 , Security , Backbone.js
 
Rest
RestRest
Rest
 
Design Web Service API by HungerStation
Design Web Service API by HungerStationDesign Web Service API by HungerStation
Design Web Service API by HungerStation
 
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
 
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
 
HTTP Basics Demo
HTTP Basics DemoHTTP Basics Demo
HTTP Basics Demo
 
Services web RESTful
Services web RESTfulServices web RESTful
Services web RESTful
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...
 

Último

Call Now ☎ 8264348440 !! Call Girls in Rani Bagh Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Rani Bagh Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Rani Bagh Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Rani Bagh Escort Service Delhi N.C.R.soniya singh
 
Al Barsha Night Partner +0567686026 Call Girls Dubai
Al Barsha Night Partner +0567686026 Call Girls  DubaiAl Barsha Night Partner +0567686026 Call Girls  Dubai
Al Barsha Night Partner +0567686026 Call Girls DubaiEscorts Call Girls
 
On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024APNIC
 
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Top Rated Pune Call Girls Daund ⟟ 6297143586 ⟟ Call Me For Genuine Sex Servi...
Top Rated  Pune Call Girls Daund ⟟ 6297143586 ⟟ Call Me For Genuine Sex Servi...Top Rated  Pune Call Girls Daund ⟟ 6297143586 ⟟ Call Me For Genuine Sex Servi...
Top Rated Pune Call Girls Daund ⟟ 6297143586 ⟟ Call Me For Genuine Sex Servi...Call Girls in Nagpur High Profile
 
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...singhpriety023
 
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...SUHANI PANDEY
 
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceEnjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceDelhi Call girls
 
Moving Beyond Twitter/X and Facebook - Social Media for local news providers
Moving Beyond Twitter/X and Facebook - Social Media for local news providersMoving Beyond Twitter/X and Facebook - Social Media for local news providers
Moving Beyond Twitter/X and Facebook - Social Media for local news providersDamian Radcliffe
 
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...SUHANI PANDEY
 
Russian Call girl in Ajman +971563133746 Ajman Call girl Service
Russian Call girl in Ajman +971563133746 Ajman Call girl ServiceRussian Call girl in Ajman +971563133746 Ajman Call girl Service
Russian Call girl in Ajman +971563133746 Ajman Call girl Servicegwenoracqe6
 
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night StandHot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Standkumarajju5765
 
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
(+971568250507 ))# Young Call Girls in Ajman By Pakistani Call Girls in ...
(+971568250507  ))#  Young Call Girls  in Ajman  By Pakistani Call Girls  in ...(+971568250507  ))#  Young Call Girls  in Ajman  By Pakistani Call Girls  in ...
(+971568250507 ))# Young Call Girls in Ajman By Pakistani Call Girls in ...Escorts Call Girls
 
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebGDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebJames Anderson
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝soniya singh
 

Último (20)

Call Girls in Prashant Vihar, Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Prashant Vihar, Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Prashant Vihar, Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Prashant Vihar, Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
 
Call Now ☎ 8264348440 !! Call Girls in Rani Bagh Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Rani Bagh Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Rani Bagh Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Rani Bagh Escort Service Delhi N.C.R.
 
Al Barsha Night Partner +0567686026 Call Girls Dubai
Al Barsha Night Partner +0567686026 Call Girls  DubaiAl Barsha Night Partner +0567686026 Call Girls  Dubai
Al Barsha Night Partner +0567686026 Call Girls Dubai
 
On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024
 
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
 
Top Rated Pune Call Girls Daund ⟟ 6297143586 ⟟ Call Me For Genuine Sex Servi...
Top Rated  Pune Call Girls Daund ⟟ 6297143586 ⟟ Call Me For Genuine Sex Servi...Top Rated  Pune Call Girls Daund ⟟ 6297143586 ⟟ Call Me For Genuine Sex Servi...
Top Rated Pune Call Girls Daund ⟟ 6297143586 ⟟ Call Me For Genuine Sex Servi...
 
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
 
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
Ganeshkhind ! Call Girls Pune - 450+ Call Girl Cash Payment 8005736733 Neha T...
 
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort ServiceEnjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
Enjoy Night⚡Call Girls Dlf City Phase 3 Gurgaon >༒8448380779 Escort Service
 
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
(INDIRA) Call Girl Pune Call Now 8250077686 Pune Escorts 24x7
 
valsad Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call Girls...
valsad Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call Girls...valsad Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call Girls...
valsad Escorts Service ☎️ 6378878445 ( Sakshi Sinha ) High Profile Call Girls...
 
Moving Beyond Twitter/X and Facebook - Social Media for local news providers
Moving Beyond Twitter/X and Facebook - Social Media for local news providersMoving Beyond Twitter/X and Facebook - Social Media for local news providers
Moving Beyond Twitter/X and Facebook - Social Media for local news providers
 
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...Russian Call Girls Pune  (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
Russian Call Girls Pune (Adult Only) 8005736733 Escort Service 24x7 Cash Pay...
 
Russian Call girl in Ajman +971563133746 Ajman Call girl Service
Russian Call girl in Ajman +971563133746 Ajman Call girl ServiceRussian Call girl in Ajman +971563133746 Ajman Call girl Service
Russian Call girl in Ajman +971563133746 Ajman Call girl Service
 
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night StandHot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
 
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
 
(+971568250507 ))# Young Call Girls in Ajman By Pakistani Call Girls in ...
(+971568250507  ))#  Young Call Girls  in Ajman  By Pakistani Call Girls  in ...(+971568250507  ))#  Young Call Girls  in Ajman  By Pakistani Call Girls  in ...
(+971568250507 ))# Young Call Girls in Ajman By Pakistani Call Girls in ...
 
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebGDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
 
Russian Call Girls in %(+971524965298 )# Call Girls in Dubai
Russian Call Girls in %(+971524965298  )#  Call Girls in DubaiRussian Call Girls in %(+971524965298  )#  Call Girls in Dubai
Russian Call Girls in %(+971524965298 )# Call Girls in Dubai
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
 

Talking Heads - writing an API does not need to be a "psycho killer"

  • 1. Talking Heads REST api’s don’t need to be your “psycho-killer”
  • 2. Dancer 2 A Lightweight WEB Framework … that does nothing wrong
  • 3. Dancer 2 A Lightweight WEB Framework … that does nothing you don’t want
  • 4. Dancer 2 A Lightweight WEB Framework … does it do what it should do?
  • 5. RESTful API’s Dancer 2 HTTP protocols and RFC’s
  • 6. Overview • HTTP 1.1 Protocol • Let’s Dance • Caching • Conditional Requests • Content Negotiation • Authorization
  • 7. HTTP/1.1 Protocol • Requests • Responses • Request Methods • Header Fields • Status codes
  • 8. HTTP 1.1 Protocol Request GET /some_resource HTTP/1.1 Host: server.tst User-Agent: insane_client/0.1 Accept: text/html; q=0.8, image/gif; q=0.3 Accept-Charset: iso8509-1 Content-Length: 123 Here can come some content, for what ever purpose
  • 9. HTTP 1.1 Protocol Request GET /some_resource HTTP/1.1 Host: server.tst User-Agent: insane_client/0.1 Accept: text/html; q=0.8, image/gif; q=0.3 Accept-Charset: iso8509-1 Content-Length: 123 Here can come some content, for what ever purpose
  • 10. HTTP 1.1 Protocol Request GET /some_resource HTTP/1.1 Host: server.tst User-Agent: insane_client/0.1 Accept: text/html; q=0.8, image/gif; q=0.3 Accept-Charset: iso8509-1 Content-Length: 123 Here can come some content, for what ever purpose
  • 11. HTTP 1.1 Protocol Request GET /some_resource HTTP/1.1 Host: server.tst User-Agent: insane_client/0.1 Accept: text/html; q=0.8, image/gif; q=0.3 Accept-Charset: iso8509-1 Content-Length: 123 Here can come some content, for what ever purpose
  • 12. HTTP 1.1 Protocol Request GET /some_resource HTTP/1.1 Host: server.tst User-Agent: insane_client/0.1 Accept: text/html; q=0.8, image/gif; q=0.3 Accept-Charset: iso8509-1 Content-Length: 123 Here can come some content, for what ever purpose
  • 13. HTTP 1.1 Protocol Response HTTP/1.1 200 OK Server: dancer/2.0 Date: Tue, 14 Oct 2014 12:34:56 GMT Content-Type: text/plain Charset: iso8509-1 Content-Length: 456 You asked for something, here it is!
  • 14. HTTP 1.1 Protocol Response HTTP/1.1 200 OK Server: dancer/2.0 Date: Tue, 14 Oct 2014 12:34:56 GMT Content-Type: text/plain Charset: iso8509-1 Content-Length: 456 You asked for something, here it is!
  • 15. HTTP 1.1 Protocol Response HTTP/1.1 200 OK Server: dancer/2.0 Date: Tue, 14 Oct 2014 12:34:56 GMT Content-Type: text/plain Charset: iso8509-1 Content-Length: 456 You asked for something, here it is!
  • 16. HTTP 1.1 Protocol Response HTTP/1.1 200 OK Server: dancer/2.0 Date: Tue, 14 Oct 2014 12:34:56 GMT Content-Type: text/plain Charset: iso8509-1 Content-Length: 456 You asked for something, here it is!
  • 17. HTTP 1.1 Protocol Response HTTP/1.1 200 OK Server: dancer/2.0 Date: Tue, 14 Oct 2014 12:34:56 GMT Content-Type: text/plain Charset: iso8509-1 Content-Length: 456 You asked for something, here it is!
  • 18. HTTP 1.1 Protocol Request Methodes • GET • POST • PUT • DELETE • HEAD • OPTIONS • PATCH
  • 19. HTTP 1.1 Protocol Header Fields • Host • User-Agent • If-Modified-Since • Content-Type • Content-Length • Location • Server • Last-Modification • Content-Type • Content-Length
  • 20. HTTP 1.1 Protocol Status Codes • 1—— Informational • 2—— Succes • 3—— Redirection • 4—— Client Error • 5—— Server
  • 23. Status: 500 Internal Server Error
  • 24. HTTP 1.1 Protocol Status 1—— Informational • 100 Continue
  • 25. HTTP 1.1 Protocol Status 2—— Succes • 200 OK • 201 Created • 202 Accepted • 204 No Content
  • 26. HTTP 1.1 Protocol Status 3—— Redirection • 300 Multiple Choices • 301 Moved Permanently • 304 Not Modified
  • 27. HTTP 1.1 Protocol Status 4—— Client Error • 400 Bad Request • 401 Unauthorized • 403 Forbidden • 404 Not Found • 405 Method Not Allowed • 407 Not Acceptable • 410 Gone • 412 Precondition Failed
  • 28. HTTP 1.1 Protocol Status 5—— Server Error • 500 Internal Server Error • 501 Not Implemented • 503 Service Unavailable
  • 29. It takes Two Dancer 2 & LWP
  • 30. Client Server Let’s Dance use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)- >find(id=>params(’id’)); template ’user.tt’, $user_info; }; dance; 1;
  • 31. Client Server Let’s Dance use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)- >find(id=>params(’id’)); template ’user.tt’, $user_info; }; dance; 1;
  • 32. Client Server Let’s Dance use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)- >find(id=>params(’id’)); template ’user.tt’, $user_info; }; dance; 1;
  • 33. Client Server Let’s Dance use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)- >find(id=>params(’id’)); template ’user.tt’, $user_info; }; dance; 1;
  • 34. Client Server Let’s Dance use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)- >find(id=>params(’id’)); template ’user.tt’, $user_info; }; dance; 1;
  • 35. Client Server Let’s Dance use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)- >find(id=>params(’id’)); template ’user.tt’, $user_info; }; dance; 1;
  • 36. Client Server LWP::UserAgent use LWP; use LWP::UserAgent; my $agent = LWP::UserAgent->new; my $response = $agent->get(’/user/999-999’);
  • 37. Caching Temporary Storage • Reduce cost • Improve Responsivness
  • 38. Caching Temporary Storage • Client Side • Public Proxy • Server Side
  • 39. Caching If-Modified-Since use LWP; use LWP::UserAgent; my $agent = LWP::UserAgent->new; my $request = HTTP::Request->new( GET => ’/user/999-999-999’); $request->header( If-Modified-Since => Tue, 14 Oct 2014 12:34:56 GMT ); my $response = $agent->request($request);
  • 40. Caching Response • Response Status: 304 Not Modified • Last-Modified: Tue, 07 Oct 2014 12:34:56 GMT • Age: 3600 • Expire: Tue, 21 Oct 2014 12:34:56 GMT • Cache-Control: public | private | max-age | no-cache
  • 41. Conditional Requests • Stateless • No Resource Locking • Only execute request if not modified since last • Only execute request if the resource is still the same
  • 42. Conditional Requests If-Unmodified-Since use LWP; use LWP::UserAgent; my $agent = LWP::UserAgent->new; my $request = HTTP::Request->new( DELETE => ’/user/999-999-999’); $request->header( If-Unmodified-Since => ’Tue, 14 Oct 2014 12:34:56 GMT’); my $response = $agent->request($request);
  • 43. Conditional Requests If-Match use LWP; use LWP::UserAgent; my $agent = LWP::UserAgent->new; my $request = HTTP::Request->new( DELETE => ’/user/999-999-999’); $request->header( If-Match => ’a23dfe4532dab7b21a83d3e0f4c2a6f1’ ); my $response = $agent->request($request);
  • 44. Conditional Requests Response • Response Status: 412 Precondition Failed • Response Status: 428 Precondition Required • Last-Modified: Tue, 07 Oct 2014 12:34:56 GMT • ETag: a23dfe4532dab7b21a83d3e0f4c2a6f1
  • 45. Content Negotiation • the same resource • another representation • the same URL • client can let the server know what type is preferred • server will try to deliver in requested content • caches need to know that this is another variant • the same URL
  • 46. Content Negotiation Resources & Representation • Uniform Resouse Identifier • Does not say anything about representation: • Charset • Encoding • Language • Format
  • 47. Content Negotiation Accept & friends • Accept: text/html, text/plain, image/png • Accept-Language: nl, en, fr • Accept-Charset: iso_ • Accept-Encoding: gzip
  • 48. Content Negotiation Accepting Preferences • The client can have some nice preferences • it might like some representation above the other • it might not like anything else • The server can only deliver some representations • it might deliver something it prefers • it might give a list of options
  • 49. Content Negotiation Mutable Serializer use Dancer2; use Dancer2::Plugin::Mutable::Serializer; get ’/user/:id’ => { my $user_info = resultset(’users’)- >find(id=>params(’id’)); return $user_info; }; 1;
  • 50. Content Negotiation Mutable Serializer use LWP; use LWP::UserAgent; my $agent = LWP::UserAgent->new; my $request = HTTP::Request->new( GET => ’/user/999-999-999’); $request->header( Accept => ’application/json’ ); my $response = $agent->request($request);
  • 51. Content Negotiation Mutable Serializer use LWP; use LWP::UserAgent; my $agent = LWP::UserAgent->new; my $request = HTTP::Request->new( GET => ’/user/999-999-999’); $request->header( Accept => ’application/json’ ); $request->header( Content-Type => ’application/xml’ ); my $response = $agent->request($request);
  • 52. Content Negotiation Let’s do things differently use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)->find(id=>params(’id’)); if (grep $_ eq ’text/html’, header(’Accept’)) { template ’user.tt’, $user_info; } if (grep $_ eq ’application/json’, header(’Accept’’)) { return to_json $user_info; } if (grep $_ eq ’application/xml’, header(’Accept’’)) { return to_xml $user_info; } }; 1;
  • 53. Content Negotiation Let’s do things differently use LWP; use LWP::UserAgent; my $agent = LWP::UserAgent->new; my $request = HTTP::Request->new( GET => ’/user/999-999-999’); $request->header( Accept => ’application/json’ ); my $response = $agent->request($request);
  • 54. Content Negotiation Let’s do things differently use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)->find(id=>params(’id’)); if (grep $_ eq ’text/html’, header(’Accept’)) { template ’user.tt’, $user_info; } if (grep $_ eq ’application/json’, header(’Accept’’)) { return to_json $user_info; } if (grep $_ eq ’application/xml’, header(’Accept’’)) { return to_xml $user_info; } }; 1;
  • 55. Content Negotiation Let’s do things differently use LWP; use LWP::UserAgent; my $agent = LWP::UserAgent->new; my $request = HTTP::Request->new( GET => ’/user/999-999-999’); $request->header( Accept => ’application/xml; q=0.1, text/html’ ); my $response = $agent->request($request);
  • 56. Content Negotiation Let’s do things differently use Dancer2; get ’/user/:id’ => { my $user_info = resultset(’users’)->find(id=>params(’id’)); if (grep $_ eq ’text/html’, header(’Accept’)) { template ’user.tt’, $user_info; } if (grep $_ eq ’application/json’, header(’Accept’’)) { return to_json $user_info; } if (grep $_ eq ’application/xml’, header(’Accept’’)) { return to_xml $user_info; } }; 1;
  • 57. Content Negotiation Let’s get Messy Accept: text/plain; q=0.3, text/html; q=0.5, */*; q=0.0 text/plain q=0.3 text/html q=0.5 */* q=0.0 «I’m fine with plain-txt, but like html more… but if it’s anything else, I DON’T WANT THAT»
  • 58. Content Negotiation Let’s get Messy use Dancer2; use Dancer2::Plugin::HTTP::ContentNegotiation; get ’/user/:id’ => { my $user_info = resultset(’users’)->find(id=>params(’id’)); http_choose_accept ( ’text/html’ => sub {template ’user.tt’, $user_info}, ’application/json’ => sub {to_json $user_info}, ’application/xml’ => sub {to_xml $user_info}, ); };
  • 59. Content Negotiation Let’s get Messy use Dancer2; use Dancer2::Plugin::HTTP::ContentNegotiation; get ’/user/:id’ => { my $user_info = resultset(’users’)- >find(id=>params(’id’)); http_choose_accept ( [’image/png’, ’image/jpg’, ’image/gif’] => sub {magick(http_accept->minor)}, ); };
  • 60. Content Negotiation Resources & Representation • Status 300: Multiple Choices • format at the end of the URL • language at the beginning of the URL • Status 406: Not Acceptable • Vary: Accept, Aceept-Language . . .
  • 61. Auth Resource Access • Stateless • Submit credentials with every request • Authentication • Username & Password • Authentication Scheme • Authorisation • Rolebased access
  • 62. Auth Usual WEB handling 1. Attempt to acces some page 2. Not Authorised ? 3. Go to /login 4. Send credentials 5. Authenticated Now ? 6. Setup session cookie 7. Go back to original requested page
  • 63. Auth REST api 1. Attempt to acces some page 2. Not Authenticated ? 3. Status: 401 “Not Authorized” 4. Resend same request including credentials 5. Authorised ? • Continue processing • Status: 403 “Forbidden”
  • 64. Auth HTTP Auth::Extensible use Dancer2; use Dancer2::Plugin::HTTP::Auth::Extensible; get '/realm' => http_require_authentication sub { "You are logged in using realm: " . http_realm }; get '/vodka' => http_require_role HardDrinker => sub { "Only hard drinkers get vodka"; };
  • 65. Auth HTTP Auth::Extensible use Dancer2; use Dancer2::Plugin::HTTP::Auth::Extensible; get '/realm' => http_require_authentication sub { "You are logged in using realm: " . http_realm }; get '/vodka' => http_require_role HardDrinker => sub { "Only hard drinkers get vodka"; };
  • 66. Auth HTTP Auth::Extensible use Dancer2; use Dancer2::Plugin::HTTP::Auth::Extensible; get '/realm' => http_require_authentication sub { "You are logged in using realm: " . http_realm }; get '/vodka' => http_require_role HardDrinker => sub { "Only hard drinkers get vodka"; };
  • 67. Auth HTTP Auth::Extensible plugins: 'HTTP::Auth::Extensible': realms: example: provider: Config users: - user: ‘beerdrinker' pass: ‘password' name: 'Beer drinker’ roles: - BeerDrinker
  • 68. Auth Resource Access • Status 401: Unauthorized • You should return a WWW-Authenticate also • HTTP Request Header Field: Authorize • Status 403: Forbidden
  • 69. Dancer2::Plugin::HTTP Family • Dancer2::Plugin::HTTP::ContentNegotiation • Dancer2::Plugin::HTTP::Auth::Extensible • Dancer2::Plugin::HTTP::Conditional • Dancer2::Plugin::HTTP::Cache
  • 70. Dancer2::Plugin::HTTP HTTP::Header::ActionPack • Authentication / Authorisation • MIME-types • DateTime conversion
  • 71. Dancer2::Plugin::HTTP HTTP::Header::ActionPack • Authentication / Authorisation • MIME-types • DateTime conversion
  • 72. Net::WebMachine HTTP::Header::ActionPack • Basho schema • Ruby implementation • Stevan Little / Dave Rolsky
  • 73. Talking Heads http://github/THEMA-MEDIA/ th.J.v.Hoesel@THEMA-MEDIA.nl