SlideShare a Scribd company logo
1 of 119
Download to read offline
PPeerrll iinn tthhee 
IInntteerrnneett ooff 
TThhiinnggss 
Dave Cross 
Magnum Solutions Ltd 
dave@mag-sol.com
 9:10 (ish) – Part 1 
 11:00 – Coffee 
 11:30 – Part 2 
 11:50 – End 
LPW 
Schedule 
 Possibly cupcakes 
8th November 2014 2
 Perl and the IoT 
 Web Client Primer 
 Web APIs with Dancer 
 Introduction to REST 
 REST APIs in Perl 
LPW 
What We Will Cover 
8th November 2014 3
PPeerrll aanndd tthhee 
IInntteerrnneett ooff 
TThhiinnggss
 Things 
 On the Internet 
 Providing useful services 
LPW 
The Internet of Things 
8th November 2014 5
LPW 
The Internet of Things 
8th November 2014 6
 Cutting edge interactions 
 Latest technologies 
 Modern languages 
LPW 
The Hype 
 Scala 
 Erlang 
8th November 2014 7
 It's just HTTP 
 Some event triggers action 
 Thing makes an HTTP request 
 Server sends response 
 Thing does something 
LPW 
The Reality 
 Usually 
8th November 2014 8
 Any language works 
 Perl just as effective as other languages 
 Perl has a long history of writing HTTP 
servers 
 And HTTP clients 
 Many useful modules 
LPW 
The Reality 
 Of course 
8th November 2014 9
 Your “thing” is an HTTP client 
 But its interface will be unusual 
 Limited input/output channels 
 Hardware sensors 
 Device::SerialPort 
 Device::BCM2835 
 Arduino workshop 
LPW 
Hardware 
8th November 2014 10
 Your “thing” won't be displaying web pages 
 So returning HTML is probably unhelpful 
 Data-rich representation 
LPW 
HTTP Response 
 JSON 
8th November 2014 11
WWeebb CClliieenntt 
PPrriimmeerr
 We're used to writing web server 
applications in Perl 
 But we can write web clients too 
 Programs that act like a browser 
 Make an HTTP request 
 Parse the HTTP reponse 
 Take some action 
LPW 
Web Clients 
 And we'll cover more about that later 
8th November 2014 13
 Most people would reach for LWP 
 LWP is “libwww-perl” 
 Library for writing web clients in Perl 
 Powerful and flexible HTTP client 
 Install from CPAN 
LPW 
LWP 
8th November 2014 14
 Small web client library for Perl 
 Part of standard Perl installation 
 Tiny is good for IoT 
LPW 
HTTP::Tiny 
 Since Perl 5.14 
8th November 2014 15
 use HTTP::Tiny; 
LPW 
Using HTTP::Tiny 
my $response = 
HTTP::Tiny->new->get('http://example.com/'); 
die "Failed!n" unless $response->{success}; 
print "$response->{status} $response->{reason}n"; 
while (my ($k, $v) = each %{$response->{headers}}) { 
for (ref $v eq 'ARRAY' ? @$v : $v) { 
print "$k: $_n"; 
} 
} 
print $response->{content} 
if length $response->{content}; 
8th November 2014 16
 Create a new user agent object (“browser”) 
with new() 
 Various configuration options 
 my $ua = HTTP::Tiny->new(%options); 
LPW 
HTTP::Tiny->new 
8th November 2014 17
 agent – user agent string 
 cookie_jar – HTTP::CookieJar object 
 default_headers – hashref 
LPW 
Options 
 Or equivalent 
8th November 2014 18
 local_address 
 keep_alive 
 max_redirect 
 max_size 
 timeout 
LPW 
Low-Level Options 
 Of response 
8th November 2014 19
 http_proxy 
 https_proxy 
 proxy 
 no_proxy 
 Environment variables 
LPW 
Proxy Options 
8th November 2014 20
 verify_SSL – default is false 
 SSL_options – passed to IO::Socket::SSL 
LPW 
SSL Options 
8th November 2014 21
 Use the request() method 
 $resp = $ua->request( 
 Useful options 
LPW 
Making Requests 
$method, $url, %options 
); 
 headers 
 content 
8th November 2014 22
 Response is a hash 
 success – true if status is 2xx 
 url – URL that returned response 
 status 
 reason 
 content 
 headers 
LPW 
Responses 
 Not an object 
8th November 2014 23
 Higher level functions for HTTP requests 
 get 
 head 
 post 
 put 
 delete 
LPW 
Easier Requests 
8th November 2014 24
 Each is a shorthand way to call request() 
 $resp = $ua->get($url, %options) 
 $resp = $ua->request( 
 Same options 
 Same response hash 
LPW 
Easier Requests 
'get', $url, %options 
) 
8th November 2014 25
 $ua->request('post', $url, 
 $ua->post($url, %options) 
 Where do post parameters go? 
 In %options 
LPW 
POSTing Data 
%options) 
 content key 
 Build it yourself 
 www_form_urlencode() 
8th November 2014 26
 $ua->post_form($url, $form_data) 
 $form_data can be hash ref 
 Or array ref 
 Sort order 
LPW 
POSTing Data 
 { key1 => 'value1', key2 => 'value2' } 
 [ key1 => 'value1', key2 => 'value2' ] 
8th November 2014 27
 HTTP::Tiny::UA 
 HTTP::Thin 
 HTTP::Tiny::Mech 
LPW 
See Also 
 Higher level UA features 
 Wrapper adds HTTP::Request/HTTP::Response 
compatibility 
 WWW::Mechanize wrapper for HTTP::Tiny 
8th November 2014 28
WWeebb AAPPIIss WWiitthh 
DDaanncceerr
LPW 
8th November 2014 
Dancer 
 Dancer is a simple route-based web 
framework for Perl 
 Easy to get web application up and running 
 See Andrew Solomon's class at 12:00 
 We're actually going to be using Dancer2
LPW 
8th November 2014 
Simple API 
 Return information about MP3s 
 GET /mp3 
 List MP3s 
 GET /mp3/1 
 Info about a single MP3
LPW 
8th November 2014 
Database 
 CREATE TABLE mp3 ( 
id integer primary key, 
title varchar(200), 
artist varchar(200), 
filename varchar(200) 
);
LPW 
8th November 2014 
DBIx::Class 
 $ dbicdump -o dump_directory=./lib 
MP3::Schema dbi:SQLite:mp3.db 
Dumping manual schema for MP3::Schema to 
directory ./lib ... 
Schema dump completed. 
 $ find lib/ 
lib/ 
lib/MP3 
lib/MP3/Schema.pm 
lib/MP3/Schema 
lib/MP3/Schema/Result 
lib/MP3/Schema/Result/Mp3.pm
LPW 
8th November 2014 
Data 
 Insert some sample data 
 sqlite> select * from mp3; 
1|Royals|Lorde|music/lorde/pure-heroine/ 
royals.mp3 
2|The Mother We Share|Chvrches| 
music/chvrches/the-bones-of-what-we-believe/the-mother- 
we-share.mp3 
3|Falling|Haim|music/haim/days-are-gone/ 
falling.mp3
LPW 
8th November 2014 
Create Application 
 $ dancer2 gen -a MP3 
 + MP3 
[ ... ] 
+ MP3/config.yml 
[ ... ] 
+ MP3/lib 
+ MP3/lib/MP3.pm 
+ MP3/bin 
+ MP3/bin/app.pl
LPW 
8th November 2014 
Run Application 
 $ MP3/bin/app.pl 
 >> Dancer2 v0.153002 server 
6219 listening on 
http://0.0.0.0:3000
LPW 
8th November 2014 
Run Application
LPW 
8th November 2014 
Implement Routes 
 Our application doesn't do anything 
 Need to implement routes 
 Routes are defined in MP3/lib/MP3.pm 
 get '/' => sub { 
template 'index'; 
};
LPW 
8th November 2014 
Implement Routes 
 Our application doesn't do anything 
 Need to implement routes 
 Routes are defined in MP3/lib/MP3.pm 
 get '/' => sub { 
template 'index'; 
};
LPW 
8th November 2014 
Implement Routes 
 Our application doesn't do anything 
 Need to implement routes 
 Routes are defined in MP3/lib/MP3.pm 
 get '/' => sub { 
template 'index'; 
};
LPW 
8th November 2014 
Implement Routes 
 Our application doesn't do anything 
 Need to implement routes 
 Routes are defined in MP3/lib/MP3.pm 
 get '/' => sub { 
template 'index'; 
};
LPW 
8th November 2014 
/mp3 Route 
 Display a list of MP3s 
 Get them from the database 
 Use Dancer2::Plugin::DBIC 
 In config.yml 
 Plugins: 
DBIC: 
default: 
dsn: dbi:SQLite:dbname=mp3.db
LPW 
8th November 2014 
/mp3 Route 
 In MP3/lib/MP3.pm 
 get '/mp3' => sub { 
my @mp3s = schema->resultset('Mp3')->all; 
content_type 'text/plain'; 
return join "n", 
map { $_->title . ' / ' . $_->artist } 
@mp3s; 
};
LPW 
8th November 2014 
/mp3 Route 
 In MP3/lib/MP3.pm 
 get '/mp3' => sub { 
my @mp3s = schema->resultset('Mp3')->all; 
content_type 'text/plain'; 
return join "n", 
map { $_->title . ' / ' . $_->artist } 
@mp3s; 
};
LPW 
8th November 2014 
/mp3 Route 
 In MP3/lib/MP3.pm 
 get '/mp3' => sub { 
my @mp3s = schema->resultset('Mp3')->all; 
content_type 'text/plain'; 
return join "n", 
map { $_->title . ' / ' . $_->artist } 
@mp3s; 
};
LPW 
8th November 2014 
/mp3 Route 
 In MP3/lib/MP3.pm 
 get '/mp3' => sub { 
my @mp3s = schema->resultset('Mp3')->all; 
content_type 'text/plain'; 
return join "n", 
map { $_->title . ' / ' . $_->artist } 
@mp3s; 
};
LPW 
8th November 2014 
/mp3 Route 
 In MP3/lib/MP3.pm 
 get '/mp3' => sub { 
my @mp3s = schema->resultset('Mp3')->all; 
content_type 'text/plain'; 
return join "n", 
map { $_->title . ' / ' . $_->artist } 
@mp3s; 
};
LPW 
8th November 2014 
/mp3 Route
LPW 
8th November 2014 
/mp3 Route
LPW 
8th November 2014 
/mp3/:id Route 
 Display details of one MP3 
 Dancer gives us parameters from path 
 $value = param($name)
LPW 
8th November 2014 
/mp3/:id Route 
 get '/mp3/:id' => sub { 
my $mp3 = 
schema->resultset('Mp3') 
->find(param('id')); 
unless ($mp3) { 
status 404; 
return 'Not found'; 
} 
content_type 'text/plain'; 
return $mp3->title . "n" . 
$mp3->artist . "n" . 
$mp3->filename; 
};
LPW 
8th November 2014 
/mp3/:id Route 
 get '/mp3/:id' => sub { 
my $mp3 = 
schema->resultset('Mp3') 
->find(param('id')); 
unless ($mp3) { 
status 404; 
return 'Not found'; 
} 
content_type 'text/plain'; 
return $mp3->title . "n" . 
$mp3->artist . "n" . 
$mp3->filename; 
};
LPW 
8th November 2014 
/mp3/:id Route 
 get '/mp3/:id' => sub { 
my $mp3 = 
schema->resultset('Mp3') 
->find(param('id')); 
unless ($mp3) { 
status 404; 
return 'Not found'; 
} 
content_type 'text/plain'; 
return $mp3->title . "n" . 
$mp3->artist . "n" . 
$mp3->filename; 
};
LPW 
8th November 2014 
/mp3/:id Route 
 get '/mp3/:id' => sub { 
my $mp3 = 
schema->resultset('Mp3') 
->find(param('id')); 
unless ($mp3) { 
status 404; 
return 'Not found'; 
} 
content_type 'text/plain'; 
return $mp3->title . "n" . 
$mp3->artist . "n" . 
$mp3->filename; 
};
LPW 
8th November 2014 
/mp3/:id Route
LPW 
8th November 2014 
/mp3/:id Route
LPW 
8th November 2014 
Plain Text? 
 Yes, plain text is bad 
 Easy fix 
 Serializer: JSON 
 In config.yml 
 Rewrite routes to return data structures 
 Dancer serialises them as JSON
LPW 
8th November 2014 
Return Data 
 get '/mp3' => sub { 
my @mp3s = schema-> 
resultset('Mp3')->all; 
return { mp3s => [ 
map { { 
title => $_->title, 
artist => $_->artist 
} } @mp3s 
] }; 
};
LPW 
8th November 2014 
Return Data 
 get '/mp3' => sub { 
my @mp3s = schema-> 
resultset('Mp3')->all; 
return { mp3s => [ 
map { { 
title => $_->title, 
artist => $_->artist 
} } @mp3s 
] }; 
};
LPW 
8th November 2014 
Return Data 
 get '/mp3' => sub { 
my @mp3s = schema-> 
resultset('Mp3')->all; 
return { mp3s => [ 
map { { 
title => $_->title, 
artist => $_->artist 
} } @mp3s 
] }; 
};
LPW 
8th November 2014 
Return Data 
 get '/mp3' => sub { 
my @mp3s = schema-> 
resultset('Mp3')->all; 
return { mp3s => [ 
map { { 
title => $_->title, 
artist => $_->artist 
} } @mp3s 
] }; 
};
LPW 
8th November 2014 
Return Data 
 get '/mp3' => sub { 
my @mp3s = schema-> 
resultset('Mp3')->all; 
return { mp3s => [ 
map { { 
title => $_->title, 
artist => $_->artist 
} } @mp3s 
] }; 
};
LPW 
8th November 2014 
Return Data 
 get '/mp3/:id' => sub { 
my $mp3 = schema-> 
resultset('Mp3')->find(param('id')); 
unless ($mp3) { 
status 404; 
return 'Not found'; 
} 
return { 
title => $mp3->title, 
artist => $mp3->artist, 
filename => $mp3->filename, 
}; 
};
LPW 
8th November 2014 
Return Data 
 get '/mp3/:id' => sub { 
my $mp3 = schema-> 
resultset('Mp3')->find(param('id')); 
unless ($mp3) { 
status 404; 
return 'Not found'; 
} 
return { $mp3->get_columns }; 
};
LPW 
8th November 2014 
JSON
LPW 
8th November 2014 
JSON
LPW 
8th November 2014 
JSON
LPW 
8th November 2014 
JSON
LPW 
8th November 2014 
URLs 
 It's good practice to return URLs when you 
can 
 Easier for clients to browse our data 
 We can do that for our list
LPW 
8th November 2014 
URLs 
 get '/mp3' => sub { 
my @mp3s = schema->resultset('Mp3')->all; 
my $url = uri_for('/mp3') . '/'; 
return { mp3s => [ 
map { { 
title => $_->title, 
artist => $_->artist, 
url => $url . $_->id, 
} } @mp3s 
] }; 
};
LPW 
8th November 2014 
URLs 
 get '/mp3' => sub { 
my @mp3s = schema->resultset('Mp3')->all; 
my $url = uri_for('/mp3') . '/'; 
return { mp3s => [ 
map { { 
title => $_->title, 
artist => $_->artist, 
url => $url . $_->id, 
} } @mp3s 
] }; 
};
LPW 
8th November 2014 
URLs 
 $ GET http://localhost:3000/mp3 
 {"mp3s":[ 
{ 
"url":"http://localhost:3000/mp3/1", 
"title":"Royals","artist":"Lorde" 
}, 
{ 
"url":"http://localhost:3000/mp3/2", 
"artist":"Chvrches","title":"The Mother We Share" 
}, 
{ 
"url":"http://localhost:3000/mp3/3", 
"artist":"Haim","title":"Falling" 
} 
]}
LPW 
8th November 2014 
More on URLs 
 Currently our system has only one resource 
 mp3 
 It's usual to have links to other resources 
 MP3s have artists 
 Link to other resources using URLs 
 Make it easier for clients to walk our data 
model
LPW 
8th November 2014 
More on URLs 
 In our MP3 JSON we have this 
 “artist”:”Lorde” 
 It would be better to have 
 “artist_name”:”Lorde” 
“artist_url”:”http://localhost:3000/artist/1” 
 Perhaps add a url() method to all of our 
objects
LPW 
8th November 2014 
Other GET Actions 
 Getting lists of objects is easy 
 Other things to consider 
 Searching 
 Sorting 
 Paging 
 Filtering 
 CGI Parameters to DBIC to SQL to JSON
LPW 
8th November 2014 
Other Actions 
 We will want to to other things to our data 
 Add objects 
 Update objects 
 Delete objects 
 CRUD operations
LPW 
8th November 2014 
Other Actions 
 Use HTTP methods 
 POST /mp3 
 Create 
 GET /mp3/:id 
 Read 
 PUT /mp3/:id 
 Update 
 DELETE /mp3/:id 
 Delete
LPW 
8th November 2014 
Other Actions 
 Use HTTP methods 
 POST /mp3 
 Create 
 GET /mp3/:id 
 Read 
 PUT /mp3/:id 
 Update 
 DELETE /mp3/:id 
 Delete
LPW 
8th November 2014 
Other Actions 
 Easy to write Dancer handlers for these 
 delete '/mp3/:id' => sub { 
schema->resultset('Mp3')-> 
find(param('id'))-> 
delete; 
} 
 But it can be hard to get right 
 What should we return here? 
 Is there a better way?
RREESSTT
 Representational State Transfer 
 Abstraction of web architecture 
 Dissertation by Roy Fielding, 2000 
 Particularly applicable to web services 
LPW 
REST 
8th November 2014 81
 Base URI for service 
 Defined media type 
 HTTP methods for interaction 
 Hypertext links for resources 
 Hypertext links for related resources 
LPW 
RESTful Web Services 
8th November 2014 82
RESTful vs Non-RESTful 
 Good test 
 Which HTTP methods does it use? 
 Web services often use only GET and POST 
 GET /delete/mp3/1 
 GET /mp3/1/delete 
 Not RESTful 
 DELETE /mp3/1 
 Might be RESTful 
LPW 
8th November 2014 83
 Dancer has a REST plugin 
 Dancer2::Plugin::REST 
 Makes our live much easier 
LPW 
RESTful Dancer 
8th November 2014 84
 Does three things for us 
 Creates routes 
 Utility functions for return values 
 Returns data in different formats 
LPW 
Dancer2::Plugin::REST 
8th November 2014 85
 resource mp3 => 
LPW 
Creates Routes 
get => sub { ... }, 
create => sub { ... }, 
delete => sub { ... }, 
update => sub { ... }; 
8th November 2014 86
 resource mp3 => 
LPW 
Creates Routes 
get => sub { ... }, 
create => sub { ... }, 
delete => sub { ... }, 
update => sub { ... }; 
8th November 2014 87
 post '/mp3' 
 get '/mp3/:id' 
 put '/mp3/:id' 
 delete '/mp3/:id' 
LPW 
CRUD Routes 
 Create 
 Read 
 Update 
 Delete 
8th November 2014 88
 post '/mp3' 
 get '/mp3/:id' 
 put '/mp3/:id' 
 delete '/mp3/:id' 
LPW 
CRUD Routes 
 Create 
 Read 
 Update 
 Delete 
8th November 2014 89
 resource mp3 => 
LPW 
Creates Routes 
get => sub { 
my $mp3 = 
schema->resultset('Mp3')-> 
find(params->{id}); 
if ($mp3) { 
status_ok( { $mp3->get_columns } ); 
} else { 
status_not_found('MP3 Not Found'); 
} 
}; 
8th November 2014 90
 Note: Still have to create main listing route 
 /mp3 
LPW 
Creates Routes 
8th November 2014 91
 Simple status_* functions for return 
values 
 status_ok(%resource) 
 status_not_found($message) 
 status_created(%new_resource) 
LPW 
Utility Functions 
8th November 2014 92
 Allow user to choose data format 
 By changing the URL 
 get '/mp3/:id' 
 get '/mp3:id.:format' 
 YAML, JSON, Data::Dumper support built-in 
LPW 
Format Options 
8th November 2014 93
Format Options - JSON 
 $ GET http://localhost:3000/mp3/1.json 
 {"id":1,"filename":"music/lorde/pure-heroine/ 
LPW 
royals.mp3","title":"Royals","ar 
tist":"Lorde"} 
8th November 2014 94
 $ GET http://localhost:3000/mp3/1.yml 
 --- 
artist: Lorde 
filename: music/lorde/pure-heroine/ 
LPW 
Format Options -YAML 
royals.mp3 
id: 1 
title: Royals 
8th November 2014 95
 $ GET http://localhost:3000/mp3/1.dump 
 $VAR1 = { 
LPW 
Format Options -YAML 
'filename' => 'music/lorde/pure-heroine/ 
royals.mp3', 
'title' => 'Royals', 
'artist' => 'Lorde', 
'id' => 1 
}; 
8th November 2014 96
 Dancer and Dancer2::Plugin::REST make 
simple REST easy 
 But full REST support is more complex 
 Here's a REST state machine 
LPW 
More Complex REST 
 Other frameworks do the same 
8th November 2014 97
LPW 
8th November 2014 98
LPW 
8th November 2014 99
LPW 
8th November 2014 100
LPW 
Read a Good Book 
8th November 2014 101
 There's a lot to think about when getting 
REST right 
 Can CPAN help? 
 Web::Machine 
 WebAPI::DBIC 
LPW 
CPAN to the Rescue 
8th November 2014 102
 Perl port of Erlang webmachine 
 You write subclasses of 
Web::Machine::Resource 
 Override methods where necessary 
 See Stevan Little's YAPC::NA 2012 talk 
LPW 
Web::Machine 
 With bits stolen from Ruby and Javascript 
versions too 
8th November 2014 103
 use Web::Machine; 
LPW 
Example 
{ 
package WasteOfTime::Resource; 
use parent 'Web::Machine::Resource'; 
use JSON::XS qw(encode_json); 
sub content_types_provided { 
[{ 'application/json' => 'to_json' }] 
} 
sub to_json { 
encode_json({ time => scalar localtime }) 
} 
} 
Web::Machine->new( 
resource => 'WasteOfTime::Resource' 
)->to_app; 
8th November 2014 104
 $ plackup time.psgi 
 $ curl -v http://0:5000 
LPW 
Example 
HTTP::Server::PSGI: Accepting connections at 
http://0:5000/ 
[ ... ] 
< HTTP/1.0 200 OK 
< Date: Sat, 08 Nov 2014 11:34:02 GMT 
< Server: HTTP::Server::PSGI 
< Content-Length: 35 
< Content-Type: application/json 
< 
* Closing connection #0 
{"time":"Sat Nov 8 11:34:02 2014"} 
8th November 2014 105
 $ curl -v http://0:5000 -H'Accept: text/html' 
LPW 
Example 
[ ... ] 
< HTTP/1.0 406 Not Acceptable 
< Date: Sat, 08 Nov 2014 11:34:02 GMT 
< Server: HTTP::Server::PSGI 
< Content-Length: 14 
< 
* Closing connection #0 
Not Acceptable 
8th November 2014 106
 sub content_types_provided { [ 
LPW 
Example 
{ 'application/json' => 'to_json' }, 
{ 'text/html' => 'to_html' }, 
] } 
8th November 2014 107
 sub content_types_provided { [ 
LPW 
Example 
{ 'application/json' => 'to_json' }, 
{ 'text/html' => 'to_html' }, 
] } 
8th November 2014 108
 sub content_types_provided { [ 
 sub to_html { 
LPW 
Example 
{ 'application/json' => 'to_json' }, 
{ 'text/html' => 'to_html' }, 
] } 
my $time = localtime; 
return “<html> 
<head><title>The Time Now Is:</title></head> 
<body> 
<h1>$time</h1> 
</body> 
</html>”; 
} 
8th November 2014 109
 $ curl -v http://0:5000 -H'Accept: text/html' 
LPW 
Example 
[ ... ] 
< HTTP/1.0 200 OK 
< Date: Sun, 09 Dec 2012 02:26:39 GMT 
< Server: HTTP::Server::PSGI 
< Vary: Accept 
< Content-Length: 103 
< Content-Type: text/html 
< 
* Closing connection #0 
<html><head><title>The Time Now 
Is:</title></head><body><h1>Sat Nov 8 11:34:02 
2014</h1></body></html> 
8th November 2014 110
 “WebAPI::DBIC provides the parts you need 
to build a feature-rich RESTful JSON web 
service API backed by DBIx::Class 
schemas.” 
 REST API in a box 
LPW 
WebAPI::DBIC 
8th November 2014 111
 Built on top of Web::Machine 
 And Path::Router 
 And Plack 
 Uses JSON+HAL 
LPW 
WebAPI::DBIC 
 Hypertext Application Language 
8th November 2014 112
 $ git clone https://github.com/timbunce/WebAPI-DBIC. 
 $ cd WebAPI-DBIC 
 $ cpanm Module::CPANfile 
 $ cpanm --installdeps . # wait ... 
 $ export WEBAPI_DBIC_SCHEMA=DummyLoadedSchema 
 $ plackup -Ilib -It/lib webapi-dbic-any.psgi 
 ... open a web browser on port 5000 to 
browse the API 
LPW 
Try It Out 
git 
8th November 2014 113
Try It Out (Your Schema) 
 $ export WEBAPI_DBIC_SCHEMA=Foo::Bar 
 $ export WEBAPI_DBIC_HTTP_AUTH_TYPE=none 
 $ export DBI_DSN=dbi:Driver:... 
 $ export DBI_USER=... 
 $ export DBI_PASS=... 
 $ plackup -Ilib webapi-dbic-any.psgi 
 ... open a web browser on port 5000 to 
browse the API 
LPW 
8th November 2014 114
CCoonncclluussiioonn
 Perl is great for the Internet of Things 
 Perl is great for text processing 
 Perl is great for network processing 
 IoT apps are often mainly HTTP transactions 
LPW 
Conclusion 
 And Perl is good at those 
8th November 2014 116
 Perl Training 
 Central London 
 Next week 
 Intermediate Perl 
 Advanced Perl 
 See advert in brochure 
LPW 
Sponsor's Message 
 11/12 Nov 
 13/14 Nov 
8th November 2014 117
 Perl Training 
 Central London 
 Next week 
 Intermediate Perl 
 Advanced Perl 
 See advert in brochure 
LPW 
Sponsor's Message 
 11/12 Nov 
 13/14 Nov 
8th November 2014 118
TThhaatt''ss AAllll FFoollkkss 
• Any Questions?

More Related Content

What's hot

Modern Perl for the Unfrozen Paleolithic Perl Programmer
Modern Perl for the Unfrozen Paleolithic  Perl ProgrammerModern Perl for the Unfrozen Paleolithic  Perl Programmer
Modern Perl for the Unfrozen Paleolithic Perl ProgrammerJohn Anderson
 
Introduction To Lamp
Introduction To LampIntroduction To Lamp
Introduction To LampAmzad Hossain
 
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
 
Serverless Ballerina
Serverless BallerinaServerless Ballerina
Serverless BallerinaBallerina
 
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010 Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010 Matt Gauger
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...Matt Gauger
 
Tobias Nyholm "Deep dive into Symfony 4 internals"
Tobias Nyholm "Deep dive into Symfony 4 internals"Tobias Nyholm "Deep dive into Symfony 4 internals"
Tobias Nyholm "Deep dive into Symfony 4 internals"Fwdays
 
Introduction to Modern Perl
Introduction to Modern PerlIntroduction to Modern Perl
Introduction to Modern PerlDave Cross
 
Creating And Consuming Web Services In Php 5
Creating And Consuming Web Services In Php 5Creating And Consuming Web Services In Php 5
Creating And Consuming Web Services In Php 5Michael Girouard
 
Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Adam Tomat
 
Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Deploying Perl apps on dotCloud
Deploying Perl apps on dotCloudDeploying Perl apps on dotCloud
Deploying Perl apps on dotClouddaoswald
 
Propel Your PHP Applications
Propel Your PHP ApplicationsPropel Your PHP Applications
Propel Your PHP Applicationshozn
 
One Person's Perspective on a Pragmatic REST Interface
One Person's Perspective on a Pragmatic REST InterfaceOne Person's Perspective on a Pragmatic REST Interface
One Person's Perspective on a Pragmatic REST Interfaceabrummett
 

What's hot (20)

Modern Perl
Modern PerlModern Perl
Modern Perl
 
Modern Perl for the Unfrozen Paleolithic Perl Programmer
Modern Perl for the Unfrozen Paleolithic  Perl ProgrammerModern Perl for the Unfrozen Paleolithic  Perl Programmer
Modern Perl for the Unfrozen Paleolithic Perl Programmer
 
Introduction To Lamp
Introduction To LampIntroduction To Lamp
Introduction To Lamp
 
4.2 PHP Function
4.2 PHP Function4.2 PHP Function
4.2 PHP Function
 
Plack at YAPC::NA 2010
Plack at YAPC::NA 2010Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
 
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
 
Develop webservice in PHP
Develop webservice in PHPDevelop webservice in PHP
Develop webservice in PHP
 
Serverless Ballerina
Serverless BallerinaServerless Ballerina
Serverless Ballerina
 
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010 Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
Matt Gauger - Lamp vs. the world - MKE PHP Users Group - December 14, 2010
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
 
CGI Presentation
CGI PresentationCGI Presentation
CGI Presentation
 
Tobias Nyholm "Deep dive into Symfony 4 internals"
Tobias Nyholm "Deep dive into Symfony 4 internals"Tobias Nyholm "Deep dive into Symfony 4 internals"
Tobias Nyholm "Deep dive into Symfony 4 internals"
 
Introduction to Modern Perl
Introduction to Modern PerlIntroduction to Modern Perl
Introduction to Modern Perl
 
Creating And Consuming Web Services In Php 5
Creating And Consuming Web Services In Php 5Creating And Consuming Web Services In Php 5
Creating And Consuming Web Services In Php 5
 
Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018
 
Building a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQueryBuilding a desktop app with HTTP::Engine, SQLite and jQuery
Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Deploying Perl apps on dotCloud
Deploying Perl apps on dotCloudDeploying Perl apps on dotCloud
Deploying Perl apps on dotCloud
 
Propel Your PHP Applications
Propel Your PHP ApplicationsPropel Your PHP Applications
Propel Your PHP Applications
 
PHP FUNCTIONS
PHP FUNCTIONSPHP FUNCTIONS
PHP FUNCTIONS
 
One Person's Perspective on a Pragmatic REST Interface
One Person's Perspective on a Pragmatic REST InterfaceOne Person's Perspective on a Pragmatic REST Interface
One Person's Perspective on a Pragmatic REST Interface
 

Viewers also liked

Prill Tecnologia - Apresentação institucional 2012
Prill Tecnologia - Apresentação institucional 2012Prill Tecnologia - Apresentação institucional 2012
Prill Tecnologia - Apresentação institucional 2012Eduardo Prillwitz
 
Prill Tecnologia - Apresentação institucional - 2011
Prill Tecnologia - Apresentação institucional - 2011Prill Tecnologia - Apresentação institucional - 2011
Prill Tecnologia - Apresentação institucional - 2011Eduardo Prillwitz
 
Perl e o Mercado de Trabalho
Perl e o Mercado de TrabalhoPerl e o Mercado de Trabalho
Perl e o Mercado de TrabalhoEduardo Prillwitz
 
Perl Moderno, dia1
Perl Moderno, dia1Perl Moderno, dia1
Perl Moderno, dia1garux
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPMichael Francis
 
Perl &lt;b>5 Tutorial&lt;/b>, First Edition
Perl &lt;b>5 Tutorial&lt;/b>, First EditionPerl &lt;b>5 Tutorial&lt;/b>, First Edition
Perl &lt;b>5 Tutorial&lt;/b>, First Editiontutorialsruby
 
Your first website in under a minute with Dancer
Your first website in under a minute with DancerYour first website in under a minute with Dancer
Your first website in under a minute with DancerxSawyer
 
Fun with Raspberry PI (and Perl)
Fun with Raspberry PI (and Perl)Fun with Raspberry PI (and Perl)
Fun with Raspberry PI (and Perl)Andrew Shitov
 
Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Tatsuhiko Miyagawa
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011leo lapworth
 
Mr 342-trafic-3
Mr 342-trafic-3Mr 342-trafic-3
Mr 342-trafic-3ReZiak
 

Viewers also liked (14)

Prill Tecnologia - Apresentação institucional 2012
Prill Tecnologia - Apresentação institucional 2012Prill Tecnologia - Apresentação institucional 2012
Prill Tecnologia - Apresentação institucional 2012
 
Prill Tecnologia - Apresentação institucional - 2011
Prill Tecnologia - Apresentação institucional - 2011Prill Tecnologia - Apresentação institucional - 2011
Prill Tecnologia - Apresentação institucional - 2011
 
Perl e o Mercado de Trabalho
Perl e o Mercado de TrabalhoPerl e o Mercado de Trabalho
Perl e o Mercado de Trabalho
 
Perl Moderno, dia1
Perl Moderno, dia1Perl Moderno, dia1
Perl Moderno, dia1
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTP
 
Dancer's Ecosystem
Dancer's EcosystemDancer's Ecosystem
Dancer's Ecosystem
 
PSGI/Plack OSDC.TW
PSGI/Plack OSDC.TWPSGI/Plack OSDC.TW
PSGI/Plack OSDC.TW
 
Perl &lt;b>5 Tutorial&lt;/b>, First Edition
Perl &lt;b>5 Tutorial&lt;/b>, First EditionPerl &lt;b>5 Tutorial&lt;/b>, First Edition
Perl &lt;b>5 Tutorial&lt;/b>, First Edition
 
Your first website in under a minute with Dancer
Your first website in under a minute with DancerYour first website in under a minute with Dancer
Your first website in under a minute with Dancer
 
Fun with Raspberry PI (and Perl)
Fun with Raspberry PI (and Perl)Fun with Raspberry PI (and Perl)
Fun with Raspberry PI (and Perl)
 
Message passing
Message passingMessage passing
Message passing
 
Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011
 
Mr 342-trafic-3
Mr 342-trafic-3Mr 342-trafic-3
Mr 342-trafic-3
 

Similar to Perl in the Internet of Things

Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyLaunchAny
 
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013Mike Desjardins
 
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
 
Querying the Web of Data with XSPARQL 1.1
Querying the Web of Data with XSPARQL 1.1Querying the Web of Data with XSPARQL 1.1
Querying the Web of Data with XSPARQL 1.1Daniele Dell'Aglio
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
10 things you need to know about leaving shared hosting
10 things you need to know about leaving shared hosting10 things you need to know about leaving shared hosting
10 things you need to know about leaving shared hostingJonathan Perlman
 
Running PHP on a Java container
Running PHP on a Java containerRunning PHP on a Java container
Running PHP on a Java containernetinhoteixeira
 
Use perl creating web services with xml rpc
Use perl creating web services with xml rpcUse perl creating web services with xml rpc
Use perl creating web services with xml rpcJohnny Pork
 
Last fm api_overview
Last fm api_overviewLast fm api_overview
Last fm api_overviewyuliang
 
Oredev 2013: Building Web Apps with Ember.js
Oredev 2013: Building Web Apps with Ember.jsOredev 2013: Building Web Apps with Ember.js
Oredev 2013: Building Web Apps with Ember.jsJesse Cravens
 
FunctionalJS - May 2014 - Streams
FunctionalJS - May 2014 - StreamsFunctionalJS - May 2014 - Streams
FunctionalJS - May 2014 - Streamsdarach
 
Talking Heads - writing an API does not need to be a "psycho killer"
Talking Heads - writing an API does not need to be a "psycho killer"Talking Heads - writing an API does not need to be a "psycho killer"
Talking Heads - writing an API does not need to be a "psycho killer"Theo van Hoesel
 
Future of HTTP in CakePHP
Future of HTTP in CakePHPFuture of HTTP in CakePHP
Future of HTTP in CakePHPmarkstory
 
PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)xSawyer
 

Similar to Perl in the Internet of Things (20)

Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
 
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013
 
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.
 
Querying the Web of Data with XSPARQL 1.1
Querying the Web of Data with XSPARQL 1.1Querying the Web of Data with XSPARQL 1.1
Querying the Web of Data with XSPARQL 1.1
 
ReactPHP
ReactPHPReactPHP
ReactPHP
 
Php hacku
Php hackuPhp hacku
Php hacku
 
Os Treat
Os TreatOs Treat
Os Treat
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
10 things you need to know about leaving shared hosting
10 things you need to know about leaving shared hosting10 things you need to know about leaving shared hosting
10 things you need to know about leaving shared hosting
 
Running PHP on a Java container
Running PHP on a Java containerRunning PHP on a Java container
Running PHP on a Java container
 
Use perl creating web services with xml rpc
Use perl creating web services with xml rpcUse perl creating web services with xml rpc
Use perl creating web services with xml rpc
 
spug_2008-08
spug_2008-08spug_2008-08
spug_2008-08
 
Last fm api_overview
Last fm api_overviewLast fm api_overview
Last fm api_overview
 
Oredev 2013: Building Web Apps with Ember.js
Oredev 2013: Building Web Apps with Ember.jsOredev 2013: Building Web Apps with Ember.js
Oredev 2013: Building Web Apps with Ember.js
 
Phpwebdevelping
PhpwebdevelpingPhpwebdevelping
Phpwebdevelping
 
FunctionalJS - May 2014 - Streams
FunctionalJS - May 2014 - StreamsFunctionalJS - May 2014 - Streams
FunctionalJS - May 2014 - Streams
 
Talking Heads - writing an API does not need to be a "psycho killer"
Talking Heads - writing an API does not need to be a "psycho killer"Talking Heads - writing an API does not need to be a "psycho killer"
Talking Heads - writing an API does not need to be a "psycho killer"
 
Future of HTTP in CakePHP
Future of HTTP in CakePHPFuture of HTTP in CakePHP
Future of HTTP in CakePHP
 
PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)
 
Phpwebdev
PhpwebdevPhpwebdev
Phpwebdev
 

More from Dave Cross

Measuring the Quality of Your Perl Code
Measuring the Quality of Your Perl CodeMeasuring the Quality of Your Perl Code
Measuring the Quality of Your Perl CodeDave Cross
 
Apollo 11 at 50 - A Simple Twitter Bot
Apollo 11 at 50 - A Simple Twitter BotApollo 11 at 50 - A Simple Twitter Bot
Apollo 11 at 50 - A Simple Twitter BotDave Cross
 
Monoliths, Balls of Mud and Silver Bullets
Monoliths, Balls of Mud and Silver BulletsMonoliths, Balls of Mud and Silver Bullets
Monoliths, Balls of Mud and Silver BulletsDave Cross
 
The Professional Programmer
The Professional ProgrammerThe Professional Programmer
The Professional ProgrammerDave Cross
 
I'm A Republic (Honest!)
I'm A Republic (Honest!)I'm A Republic (Honest!)
I'm A Republic (Honest!)Dave Cross
 
Web Site Tune-Up - Improve Your Googlejuice
Web Site Tune-Up - Improve Your GooglejuiceWeb Site Tune-Up - Improve Your Googlejuice
Web Site Tune-Up - Improve Your GooglejuiceDave Cross
 
Freeing Tower Bridge
Freeing Tower BridgeFreeing Tower Bridge
Freeing Tower BridgeDave Cross
 
Modern Perl Catch-Up
Modern Perl Catch-UpModern Perl Catch-Up
Modern Perl Catch-UpDave Cross
 
Error(s) Free Programming
Error(s) Free ProgrammingError(s) Free Programming
Error(s) Free ProgrammingDave Cross
 
Improving Dev Assistant
Improving Dev AssistantImproving Dev Assistant
Improving Dev AssistantDave Cross
 
Conference Driven Publishing
Conference Driven PublishingConference Driven Publishing
Conference Driven PublishingDave Cross
 
Conference Driven Publishing
Conference Driven PublishingConference Driven Publishing
Conference Driven PublishingDave Cross
 
Return to the Kingdom of the Blind
Return to the Kingdom of the BlindReturn to the Kingdom of the Blind
Return to the Kingdom of the BlindDave Cross
 
Github, Travis-CI and Perl
Github, Travis-CI and PerlGithub, Travis-CI and Perl
Github, Travis-CI and PerlDave Cross
 
Object-Oriented Programming with Perl and Moose
Object-Oriented Programming with Perl and MooseObject-Oriented Programming with Perl and Moose
Object-Oriented Programming with Perl and MooseDave Cross
 
Database Programming with Perl and DBIx::Class
Database Programming with Perl and DBIx::ClassDatabase Programming with Perl and DBIx::Class
Database Programming with Perl and DBIx::ClassDave Cross
 
Modern Perl for Non-Perl Programmers
Modern Perl for Non-Perl ProgrammersModern Perl for Non-Perl Programmers
Modern Perl for Non-Perl ProgrammersDave Cross
 
Matt's PSGI Archive
Matt's PSGI ArchiveMatt's PSGI Archive
Matt's PSGI ArchiveDave Cross
 

More from Dave Cross (20)

Measuring the Quality of Your Perl Code
Measuring the Quality of Your Perl CodeMeasuring the Quality of Your Perl Code
Measuring the Quality of Your Perl Code
 
Apollo 11 at 50 - A Simple Twitter Bot
Apollo 11 at 50 - A Simple Twitter BotApollo 11 at 50 - A Simple Twitter Bot
Apollo 11 at 50 - A Simple Twitter Bot
 
Monoliths, Balls of Mud and Silver Bullets
Monoliths, Balls of Mud and Silver BulletsMonoliths, Balls of Mud and Silver Bullets
Monoliths, Balls of Mud and Silver Bullets
 
The Professional Programmer
The Professional ProgrammerThe Professional Programmer
The Professional Programmer
 
I'm A Republic (Honest!)
I'm A Republic (Honest!)I'm A Republic (Honest!)
I'm A Republic (Honest!)
 
Web Site Tune-Up - Improve Your Googlejuice
Web Site Tune-Up - Improve Your GooglejuiceWeb Site Tune-Up - Improve Your Googlejuice
Web Site Tune-Up - Improve Your Googlejuice
 
Freeing Tower Bridge
Freeing Tower BridgeFreeing Tower Bridge
Freeing Tower Bridge
 
Modern Perl Catch-Up
Modern Perl Catch-UpModern Perl Catch-Up
Modern Perl Catch-Up
 
Error(s) Free Programming
Error(s) Free ProgrammingError(s) Free Programming
Error(s) Free Programming
 
Medium Perl
Medium PerlMedium Perl
Medium Perl
 
Improving Dev Assistant
Improving Dev AssistantImproving Dev Assistant
Improving Dev Assistant
 
Conference Driven Publishing
Conference Driven PublishingConference Driven Publishing
Conference Driven Publishing
 
Conference Driven Publishing
Conference Driven PublishingConference Driven Publishing
Conference Driven Publishing
 
TwittElection
TwittElectionTwittElection
TwittElection
 
Return to the Kingdom of the Blind
Return to the Kingdom of the BlindReturn to the Kingdom of the Blind
Return to the Kingdom of the Blind
 
Github, Travis-CI and Perl
Github, Travis-CI and PerlGithub, Travis-CI and Perl
Github, Travis-CI and Perl
 
Object-Oriented Programming with Perl and Moose
Object-Oriented Programming with Perl and MooseObject-Oriented Programming with Perl and Moose
Object-Oriented Programming with Perl and Moose
 
Database Programming with Perl and DBIx::Class
Database Programming with Perl and DBIx::ClassDatabase Programming with Perl and DBIx::Class
Database Programming with Perl and DBIx::Class
 
Modern Perl for Non-Perl Programmers
Modern Perl for Non-Perl ProgrammersModern Perl for Non-Perl Programmers
Modern Perl for Non-Perl Programmers
 
Matt's PSGI Archive
Matt's PSGI ArchiveMatt's PSGI Archive
Matt's PSGI Archive
 

Recently uploaded

A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

Perl in the Internet of Things

  • 1. PPeerrll iinn tthhee IInntteerrnneett ooff TThhiinnggss Dave Cross Magnum Solutions Ltd dave@mag-sol.com
  • 2.  9:10 (ish) – Part 1  11:00 – Coffee  11:30 – Part 2  11:50 – End LPW Schedule  Possibly cupcakes 8th November 2014 2
  • 3.  Perl and the IoT  Web Client Primer  Web APIs with Dancer  Introduction to REST  REST APIs in Perl LPW What We Will Cover 8th November 2014 3
  • 4. PPeerrll aanndd tthhee IInntteerrnneett ooff TThhiinnggss
  • 5.  Things  On the Internet  Providing useful services LPW The Internet of Things 8th November 2014 5
  • 6. LPW The Internet of Things 8th November 2014 6
  • 7.  Cutting edge interactions  Latest technologies  Modern languages LPW The Hype  Scala  Erlang 8th November 2014 7
  • 8.  It's just HTTP  Some event triggers action  Thing makes an HTTP request  Server sends response  Thing does something LPW The Reality  Usually 8th November 2014 8
  • 9.  Any language works  Perl just as effective as other languages  Perl has a long history of writing HTTP servers  And HTTP clients  Many useful modules LPW The Reality  Of course 8th November 2014 9
  • 10.  Your “thing” is an HTTP client  But its interface will be unusual  Limited input/output channels  Hardware sensors  Device::SerialPort  Device::BCM2835  Arduino workshop LPW Hardware 8th November 2014 10
  • 11.  Your “thing” won't be displaying web pages  So returning HTML is probably unhelpful  Data-rich representation LPW HTTP Response  JSON 8th November 2014 11
  • 13.  We're used to writing web server applications in Perl  But we can write web clients too  Programs that act like a browser  Make an HTTP request  Parse the HTTP reponse  Take some action LPW Web Clients  And we'll cover more about that later 8th November 2014 13
  • 14.  Most people would reach for LWP  LWP is “libwww-perl”  Library for writing web clients in Perl  Powerful and flexible HTTP client  Install from CPAN LPW LWP 8th November 2014 14
  • 15.  Small web client library for Perl  Part of standard Perl installation  Tiny is good for IoT LPW HTTP::Tiny  Since Perl 5.14 8th November 2014 15
  • 16.  use HTTP::Tiny; LPW Using HTTP::Tiny my $response = HTTP::Tiny->new->get('http://example.com/'); die "Failed!n" unless $response->{success}; print "$response->{status} $response->{reason}n"; while (my ($k, $v) = each %{$response->{headers}}) { for (ref $v eq 'ARRAY' ? @$v : $v) { print "$k: $_n"; } } print $response->{content} if length $response->{content}; 8th November 2014 16
  • 17.  Create a new user agent object (“browser”) with new()  Various configuration options  my $ua = HTTP::Tiny->new(%options); LPW HTTP::Tiny->new 8th November 2014 17
  • 18.  agent – user agent string  cookie_jar – HTTP::CookieJar object  default_headers – hashref LPW Options  Or equivalent 8th November 2014 18
  • 19.  local_address  keep_alive  max_redirect  max_size  timeout LPW Low-Level Options  Of response 8th November 2014 19
  • 20.  http_proxy  https_proxy  proxy  no_proxy  Environment variables LPW Proxy Options 8th November 2014 20
  • 21.  verify_SSL – default is false  SSL_options – passed to IO::Socket::SSL LPW SSL Options 8th November 2014 21
  • 22.  Use the request() method  $resp = $ua->request(  Useful options LPW Making Requests $method, $url, %options );  headers  content 8th November 2014 22
  • 23.  Response is a hash  success – true if status is 2xx  url – URL that returned response  status  reason  content  headers LPW Responses  Not an object 8th November 2014 23
  • 24.  Higher level functions for HTTP requests  get  head  post  put  delete LPW Easier Requests 8th November 2014 24
  • 25.  Each is a shorthand way to call request()  $resp = $ua->get($url, %options)  $resp = $ua->request(  Same options  Same response hash LPW Easier Requests 'get', $url, %options ) 8th November 2014 25
  • 26.  $ua->request('post', $url,  $ua->post($url, %options)  Where do post parameters go?  In %options LPW POSTing Data %options)  content key  Build it yourself  www_form_urlencode() 8th November 2014 26
  • 27.  $ua->post_form($url, $form_data)  $form_data can be hash ref  Or array ref  Sort order LPW POSTing Data  { key1 => 'value1', key2 => 'value2' }  [ key1 => 'value1', key2 => 'value2' ] 8th November 2014 27
  • 28.  HTTP::Tiny::UA  HTTP::Thin  HTTP::Tiny::Mech LPW See Also  Higher level UA features  Wrapper adds HTTP::Request/HTTP::Response compatibility  WWW::Mechanize wrapper for HTTP::Tiny 8th November 2014 28
  • 29. WWeebb AAPPIIss WWiitthh DDaanncceerr
  • 30. LPW 8th November 2014 Dancer  Dancer is a simple route-based web framework for Perl  Easy to get web application up and running  See Andrew Solomon's class at 12:00  We're actually going to be using Dancer2
  • 31. LPW 8th November 2014 Simple API  Return information about MP3s  GET /mp3  List MP3s  GET /mp3/1  Info about a single MP3
  • 32. LPW 8th November 2014 Database  CREATE TABLE mp3 ( id integer primary key, title varchar(200), artist varchar(200), filename varchar(200) );
  • 33. LPW 8th November 2014 DBIx::Class  $ dbicdump -o dump_directory=./lib MP3::Schema dbi:SQLite:mp3.db Dumping manual schema for MP3::Schema to directory ./lib ... Schema dump completed.  $ find lib/ lib/ lib/MP3 lib/MP3/Schema.pm lib/MP3/Schema lib/MP3/Schema/Result lib/MP3/Schema/Result/Mp3.pm
  • 34. LPW 8th November 2014 Data  Insert some sample data  sqlite> select * from mp3; 1|Royals|Lorde|music/lorde/pure-heroine/ royals.mp3 2|The Mother We Share|Chvrches| music/chvrches/the-bones-of-what-we-believe/the-mother- we-share.mp3 3|Falling|Haim|music/haim/days-are-gone/ falling.mp3
  • 35. LPW 8th November 2014 Create Application  $ dancer2 gen -a MP3  + MP3 [ ... ] + MP3/config.yml [ ... ] + MP3/lib + MP3/lib/MP3.pm + MP3/bin + MP3/bin/app.pl
  • 36. LPW 8th November 2014 Run Application  $ MP3/bin/app.pl  >> Dancer2 v0.153002 server 6219 listening on http://0.0.0.0:3000
  • 37. LPW 8th November 2014 Run Application
  • 38. LPW 8th November 2014 Implement Routes  Our application doesn't do anything  Need to implement routes  Routes are defined in MP3/lib/MP3.pm  get '/' => sub { template 'index'; };
  • 39. LPW 8th November 2014 Implement Routes  Our application doesn't do anything  Need to implement routes  Routes are defined in MP3/lib/MP3.pm  get '/' => sub { template 'index'; };
  • 40. LPW 8th November 2014 Implement Routes  Our application doesn't do anything  Need to implement routes  Routes are defined in MP3/lib/MP3.pm  get '/' => sub { template 'index'; };
  • 41. LPW 8th November 2014 Implement Routes  Our application doesn't do anything  Need to implement routes  Routes are defined in MP3/lib/MP3.pm  get '/' => sub { template 'index'; };
  • 42. LPW 8th November 2014 /mp3 Route  Display a list of MP3s  Get them from the database  Use Dancer2::Plugin::DBIC  In config.yml  Plugins: DBIC: default: dsn: dbi:SQLite:dbname=mp3.db
  • 43. LPW 8th November 2014 /mp3 Route  In MP3/lib/MP3.pm  get '/mp3' => sub { my @mp3s = schema->resultset('Mp3')->all; content_type 'text/plain'; return join "n", map { $_->title . ' / ' . $_->artist } @mp3s; };
  • 44. LPW 8th November 2014 /mp3 Route  In MP3/lib/MP3.pm  get '/mp3' => sub { my @mp3s = schema->resultset('Mp3')->all; content_type 'text/plain'; return join "n", map { $_->title . ' / ' . $_->artist } @mp3s; };
  • 45. LPW 8th November 2014 /mp3 Route  In MP3/lib/MP3.pm  get '/mp3' => sub { my @mp3s = schema->resultset('Mp3')->all; content_type 'text/plain'; return join "n", map { $_->title . ' / ' . $_->artist } @mp3s; };
  • 46. LPW 8th November 2014 /mp3 Route  In MP3/lib/MP3.pm  get '/mp3' => sub { my @mp3s = schema->resultset('Mp3')->all; content_type 'text/plain'; return join "n", map { $_->title . ' / ' . $_->artist } @mp3s; };
  • 47. LPW 8th November 2014 /mp3 Route  In MP3/lib/MP3.pm  get '/mp3' => sub { my @mp3s = schema->resultset('Mp3')->all; content_type 'text/plain'; return join "n", map { $_->title . ' / ' . $_->artist } @mp3s; };
  • 48. LPW 8th November 2014 /mp3 Route
  • 49. LPW 8th November 2014 /mp3 Route
  • 50. LPW 8th November 2014 /mp3/:id Route  Display details of one MP3  Dancer gives us parameters from path  $value = param($name)
  • 51. LPW 8th November 2014 /mp3/:id Route  get '/mp3/:id' => sub { my $mp3 = schema->resultset('Mp3') ->find(param('id')); unless ($mp3) { status 404; return 'Not found'; } content_type 'text/plain'; return $mp3->title . "n" . $mp3->artist . "n" . $mp3->filename; };
  • 52. LPW 8th November 2014 /mp3/:id Route  get '/mp3/:id' => sub { my $mp3 = schema->resultset('Mp3') ->find(param('id')); unless ($mp3) { status 404; return 'Not found'; } content_type 'text/plain'; return $mp3->title . "n" . $mp3->artist . "n" . $mp3->filename; };
  • 53. LPW 8th November 2014 /mp3/:id Route  get '/mp3/:id' => sub { my $mp3 = schema->resultset('Mp3') ->find(param('id')); unless ($mp3) { status 404; return 'Not found'; } content_type 'text/plain'; return $mp3->title . "n" . $mp3->artist . "n" . $mp3->filename; };
  • 54. LPW 8th November 2014 /mp3/:id Route  get '/mp3/:id' => sub { my $mp3 = schema->resultset('Mp3') ->find(param('id')); unless ($mp3) { status 404; return 'Not found'; } content_type 'text/plain'; return $mp3->title . "n" . $mp3->artist . "n" . $mp3->filename; };
  • 55. LPW 8th November 2014 /mp3/:id Route
  • 56. LPW 8th November 2014 /mp3/:id Route
  • 57. LPW 8th November 2014 Plain Text?  Yes, plain text is bad  Easy fix  Serializer: JSON  In config.yml  Rewrite routes to return data structures  Dancer serialises them as JSON
  • 58. LPW 8th November 2014 Return Data  get '/mp3' => sub { my @mp3s = schema-> resultset('Mp3')->all; return { mp3s => [ map { { title => $_->title, artist => $_->artist } } @mp3s ] }; };
  • 59. LPW 8th November 2014 Return Data  get '/mp3' => sub { my @mp3s = schema-> resultset('Mp3')->all; return { mp3s => [ map { { title => $_->title, artist => $_->artist } } @mp3s ] }; };
  • 60. LPW 8th November 2014 Return Data  get '/mp3' => sub { my @mp3s = schema-> resultset('Mp3')->all; return { mp3s => [ map { { title => $_->title, artist => $_->artist } } @mp3s ] }; };
  • 61. LPW 8th November 2014 Return Data  get '/mp3' => sub { my @mp3s = schema-> resultset('Mp3')->all; return { mp3s => [ map { { title => $_->title, artist => $_->artist } } @mp3s ] }; };
  • 62. LPW 8th November 2014 Return Data  get '/mp3' => sub { my @mp3s = schema-> resultset('Mp3')->all; return { mp3s => [ map { { title => $_->title, artist => $_->artist } } @mp3s ] }; };
  • 63. LPW 8th November 2014 Return Data  get '/mp3/:id' => sub { my $mp3 = schema-> resultset('Mp3')->find(param('id')); unless ($mp3) { status 404; return 'Not found'; } return { title => $mp3->title, artist => $mp3->artist, filename => $mp3->filename, }; };
  • 64. LPW 8th November 2014 Return Data  get '/mp3/:id' => sub { my $mp3 = schema-> resultset('Mp3')->find(param('id')); unless ($mp3) { status 404; return 'Not found'; } return { $mp3->get_columns }; };
  • 65. LPW 8th November 2014 JSON
  • 66. LPW 8th November 2014 JSON
  • 67. LPW 8th November 2014 JSON
  • 68. LPW 8th November 2014 JSON
  • 69. LPW 8th November 2014 URLs  It's good practice to return URLs when you can  Easier for clients to browse our data  We can do that for our list
  • 70. LPW 8th November 2014 URLs  get '/mp3' => sub { my @mp3s = schema->resultset('Mp3')->all; my $url = uri_for('/mp3') . '/'; return { mp3s => [ map { { title => $_->title, artist => $_->artist, url => $url . $_->id, } } @mp3s ] }; };
  • 71. LPW 8th November 2014 URLs  get '/mp3' => sub { my @mp3s = schema->resultset('Mp3')->all; my $url = uri_for('/mp3') . '/'; return { mp3s => [ map { { title => $_->title, artist => $_->artist, url => $url . $_->id, } } @mp3s ] }; };
  • 72. LPW 8th November 2014 URLs  $ GET http://localhost:3000/mp3  {"mp3s":[ { "url":"http://localhost:3000/mp3/1", "title":"Royals","artist":"Lorde" }, { "url":"http://localhost:3000/mp3/2", "artist":"Chvrches","title":"The Mother We Share" }, { "url":"http://localhost:3000/mp3/3", "artist":"Haim","title":"Falling" } ]}
  • 73. LPW 8th November 2014 More on URLs  Currently our system has only one resource  mp3  It's usual to have links to other resources  MP3s have artists  Link to other resources using URLs  Make it easier for clients to walk our data model
  • 74. LPW 8th November 2014 More on URLs  In our MP3 JSON we have this  “artist”:”Lorde”  It would be better to have  “artist_name”:”Lorde” “artist_url”:”http://localhost:3000/artist/1”  Perhaps add a url() method to all of our objects
  • 75. LPW 8th November 2014 Other GET Actions  Getting lists of objects is easy  Other things to consider  Searching  Sorting  Paging  Filtering  CGI Parameters to DBIC to SQL to JSON
  • 76. LPW 8th November 2014 Other Actions  We will want to to other things to our data  Add objects  Update objects  Delete objects  CRUD operations
  • 77. LPW 8th November 2014 Other Actions  Use HTTP methods  POST /mp3  Create  GET /mp3/:id  Read  PUT /mp3/:id  Update  DELETE /mp3/:id  Delete
  • 78. LPW 8th November 2014 Other Actions  Use HTTP methods  POST /mp3  Create  GET /mp3/:id  Read  PUT /mp3/:id  Update  DELETE /mp3/:id  Delete
  • 79. LPW 8th November 2014 Other Actions  Easy to write Dancer handlers for these  delete '/mp3/:id' => sub { schema->resultset('Mp3')-> find(param('id'))-> delete; }  But it can be hard to get right  What should we return here?  Is there a better way?
  • 81.  Representational State Transfer  Abstraction of web architecture  Dissertation by Roy Fielding, 2000  Particularly applicable to web services LPW REST 8th November 2014 81
  • 82.  Base URI for service  Defined media type  HTTP methods for interaction  Hypertext links for resources  Hypertext links for related resources LPW RESTful Web Services 8th November 2014 82
  • 83. RESTful vs Non-RESTful  Good test  Which HTTP methods does it use?  Web services often use only GET and POST  GET /delete/mp3/1  GET /mp3/1/delete  Not RESTful  DELETE /mp3/1  Might be RESTful LPW 8th November 2014 83
  • 84.  Dancer has a REST plugin  Dancer2::Plugin::REST  Makes our live much easier LPW RESTful Dancer 8th November 2014 84
  • 85.  Does three things for us  Creates routes  Utility functions for return values  Returns data in different formats LPW Dancer2::Plugin::REST 8th November 2014 85
  • 86.  resource mp3 => LPW Creates Routes get => sub { ... }, create => sub { ... }, delete => sub { ... }, update => sub { ... }; 8th November 2014 86
  • 87.  resource mp3 => LPW Creates Routes get => sub { ... }, create => sub { ... }, delete => sub { ... }, update => sub { ... }; 8th November 2014 87
  • 88.  post '/mp3'  get '/mp3/:id'  put '/mp3/:id'  delete '/mp3/:id' LPW CRUD Routes  Create  Read  Update  Delete 8th November 2014 88
  • 89.  post '/mp3'  get '/mp3/:id'  put '/mp3/:id'  delete '/mp3/:id' LPW CRUD Routes  Create  Read  Update  Delete 8th November 2014 89
  • 90.  resource mp3 => LPW Creates Routes get => sub { my $mp3 = schema->resultset('Mp3')-> find(params->{id}); if ($mp3) { status_ok( { $mp3->get_columns } ); } else { status_not_found('MP3 Not Found'); } }; 8th November 2014 90
  • 91.  Note: Still have to create main listing route  /mp3 LPW Creates Routes 8th November 2014 91
  • 92.  Simple status_* functions for return values  status_ok(%resource)  status_not_found($message)  status_created(%new_resource) LPW Utility Functions 8th November 2014 92
  • 93.  Allow user to choose data format  By changing the URL  get '/mp3/:id'  get '/mp3:id.:format'  YAML, JSON, Data::Dumper support built-in LPW Format Options 8th November 2014 93
  • 94. Format Options - JSON  $ GET http://localhost:3000/mp3/1.json  {"id":1,"filename":"music/lorde/pure-heroine/ LPW royals.mp3","title":"Royals","ar tist":"Lorde"} 8th November 2014 94
  • 95.  $ GET http://localhost:3000/mp3/1.yml  --- artist: Lorde filename: music/lorde/pure-heroine/ LPW Format Options -YAML royals.mp3 id: 1 title: Royals 8th November 2014 95
  • 96.  $ GET http://localhost:3000/mp3/1.dump  $VAR1 = { LPW Format Options -YAML 'filename' => 'music/lorde/pure-heroine/ royals.mp3', 'title' => 'Royals', 'artist' => 'Lorde', 'id' => 1 }; 8th November 2014 96
  • 97.  Dancer and Dancer2::Plugin::REST make simple REST easy  But full REST support is more complex  Here's a REST state machine LPW More Complex REST  Other frameworks do the same 8th November 2014 97
  • 98. LPW 8th November 2014 98
  • 99. LPW 8th November 2014 99
  • 100. LPW 8th November 2014 100
  • 101. LPW Read a Good Book 8th November 2014 101
  • 102.  There's a lot to think about when getting REST right  Can CPAN help?  Web::Machine  WebAPI::DBIC LPW CPAN to the Rescue 8th November 2014 102
  • 103.  Perl port of Erlang webmachine  You write subclasses of Web::Machine::Resource  Override methods where necessary  See Stevan Little's YAPC::NA 2012 talk LPW Web::Machine  With bits stolen from Ruby and Javascript versions too 8th November 2014 103
  • 104.  use Web::Machine; LPW Example { package WasteOfTime::Resource; use parent 'Web::Machine::Resource'; use JSON::XS qw(encode_json); sub content_types_provided { [{ 'application/json' => 'to_json' }] } sub to_json { encode_json({ time => scalar localtime }) } } Web::Machine->new( resource => 'WasteOfTime::Resource' )->to_app; 8th November 2014 104
  • 105.  $ plackup time.psgi  $ curl -v http://0:5000 LPW Example HTTP::Server::PSGI: Accepting connections at http://0:5000/ [ ... ] < HTTP/1.0 200 OK < Date: Sat, 08 Nov 2014 11:34:02 GMT < Server: HTTP::Server::PSGI < Content-Length: 35 < Content-Type: application/json < * Closing connection #0 {"time":"Sat Nov 8 11:34:02 2014"} 8th November 2014 105
  • 106.  $ curl -v http://0:5000 -H'Accept: text/html' LPW Example [ ... ] < HTTP/1.0 406 Not Acceptable < Date: Sat, 08 Nov 2014 11:34:02 GMT < Server: HTTP::Server::PSGI < Content-Length: 14 < * Closing connection #0 Not Acceptable 8th November 2014 106
  • 107.  sub content_types_provided { [ LPW Example { 'application/json' => 'to_json' }, { 'text/html' => 'to_html' }, ] } 8th November 2014 107
  • 108.  sub content_types_provided { [ LPW Example { 'application/json' => 'to_json' }, { 'text/html' => 'to_html' }, ] } 8th November 2014 108
  • 109.  sub content_types_provided { [  sub to_html { LPW Example { 'application/json' => 'to_json' }, { 'text/html' => 'to_html' }, ] } my $time = localtime; return “<html> <head><title>The Time Now Is:</title></head> <body> <h1>$time</h1> </body> </html>”; } 8th November 2014 109
  • 110.  $ curl -v http://0:5000 -H'Accept: text/html' LPW Example [ ... ] < HTTP/1.0 200 OK < Date: Sun, 09 Dec 2012 02:26:39 GMT < Server: HTTP::Server::PSGI < Vary: Accept < Content-Length: 103 < Content-Type: text/html < * Closing connection #0 <html><head><title>The Time Now Is:</title></head><body><h1>Sat Nov 8 11:34:02 2014</h1></body></html> 8th November 2014 110
  • 111.  “WebAPI::DBIC provides the parts you need to build a feature-rich RESTful JSON web service API backed by DBIx::Class schemas.”  REST API in a box LPW WebAPI::DBIC 8th November 2014 111
  • 112.  Built on top of Web::Machine  And Path::Router  And Plack  Uses JSON+HAL LPW WebAPI::DBIC  Hypertext Application Language 8th November 2014 112
  • 113.  $ git clone https://github.com/timbunce/WebAPI-DBIC.  $ cd WebAPI-DBIC  $ cpanm Module::CPANfile  $ cpanm --installdeps . # wait ...  $ export WEBAPI_DBIC_SCHEMA=DummyLoadedSchema  $ plackup -Ilib -It/lib webapi-dbic-any.psgi  ... open a web browser on port 5000 to browse the API LPW Try It Out git 8th November 2014 113
  • 114. Try It Out (Your Schema)  $ export WEBAPI_DBIC_SCHEMA=Foo::Bar  $ export WEBAPI_DBIC_HTTP_AUTH_TYPE=none  $ export DBI_DSN=dbi:Driver:...  $ export DBI_USER=...  $ export DBI_PASS=...  $ plackup -Ilib webapi-dbic-any.psgi  ... open a web browser on port 5000 to browse the API LPW 8th November 2014 114
  • 116.  Perl is great for the Internet of Things  Perl is great for text processing  Perl is great for network processing  IoT apps are often mainly HTTP transactions LPW Conclusion  And Perl is good at those 8th November 2014 116
  • 117.  Perl Training  Central London  Next week  Intermediate Perl  Advanced Perl  See advert in brochure LPW Sponsor's Message  11/12 Nov  13/14 Nov 8th November 2014 117
  • 118.  Perl Training  Central London  Next week  Intermediate Perl  Advanced Perl  See advert in brochure LPW Sponsor's Message  11/12 Nov  13/14 Nov 8th November 2014 118
  • 119. TThhaatt''ss AAllll FFoollkkss • Any Questions?