making your perl rest
TRANSCRIPT
![Page 1: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/1.jpg)
Making Your Perl REST Sterling Hanenkamp, PPW 2008
![Page 2: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/2.jpg)
What is REST?
![Page 3: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/3.jpg)
What is REST?
• Ever heard of...
![Page 4: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/4.jpg)
What is REST?
• Ever heard of...
• SOAP?
![Page 5: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/5.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
![Page 6: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/6.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
![Page 7: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/7.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
• WebDAV?
![Page 8: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/8.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
• WebDAV?
• It’s kind of like that.
![Page 9: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/9.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
• WebDAV?
• It’s kind of like that.
• Ever heard of...
![Page 10: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/10.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
• WebDAV?
• It’s kind of like that.
• Ever heard of...
• HTTP?
![Page 11: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/11.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
• WebDAV?
• It’s kind of like that.
• Ever heard of...
• HTTP?
• XML?
![Page 12: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/12.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
• WebDAV?
• It’s kind of like that.
• Ever heard of...
• HTTP?
• XML?
• YAML?
![Page 13: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/13.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
• WebDAV?
• It’s kind of like that.
• Ever heard of...
• HTTP?
• XML?
• YAML?
• JSON?
![Page 14: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/14.jpg)
What is REST?
• Ever heard of...
• SOAP?
• RPC?
• XML-RPC?
• WebDAV?
• It’s kind of like that.
• Ever heard of...
• HTTP?
• XML?
• YAML?
• JSON?
• It’s kind of like that too
![Page 15: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/15.jpg)
What are we NOT talking about?
![Page 16: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/16.jpg)
• REST is a general purpose term
What are we NOT talking about?
![Page 17: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/17.jpg)
• REST is a general purpose term
• I’m not talking about a general notion
What are we NOT talking about?
![Page 18: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/18.jpg)
• REST is a general purpose term
• I’m not talking about a general notion
• We’re talking about REST APIs
What are we NOT talking about?
![Page 19: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/19.jpg)
• REST is a general purpose term
• I’m not talking about a general notion
• We’re talking about REST APIs
• Web Services
What are we NOT talking about?
![Page 20: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/20.jpg)
• REST is a general purpose term
• I’m not talking about a general notion
• We’re talking about REST APIs
• Web Services
• Mashups!!!! Web 2.0!!! Yippee!!!
What are we NOT talking about?
![Page 21: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/21.jpg)
• REST is a general purpose term
• I’m not talking about a general notion
• We’re talking about REST APIs
• Web Services
• Mashups!!!! Web 2.0!!! Yippee!!!
What are we NOT talking about?
![Page 22: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/22.jpg)
• REST is a general purpose term
• I’m not talking about a general notion
• We’re talking about REST APIs
• Web Services
• Mashups!!!! Web 2.0!!! Yippee!!!
• I’ve used my lifetime supply of exclamation points...
What are we NOT talking about?
![Page 23: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/23.jpg)
The REST Triangle
![Page 24: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/24.jpg)
The REST Triangle
nouns http://www.onlamp.com
ver
bs
GET, P
OST, P
UT, DEL
ETE
content typesYAML, XML, JSON, etc.
![Page 25: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/25.jpg)
The REST Triangle
• Nouns (=URL)nouns http://www.onlamp.com
ver
bs
GET, P
OST, P
UT, DEL
ETE
content typesYAML, XML, JSON, etc.
![Page 26: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/26.jpg)
The REST Triangle
• Nouns (=URL)
• Verbs (=HTTP METHOD)
nouns http://www.onlamp.com
ver
bs
GET, P
OST, P
UT, DEL
ETE
content typesYAML, XML, JSON, etc.
![Page 27: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/27.jpg)
The REST Triangle
• Nouns (=URL)
• Verbs (=HTTP METHOD)
• Content (=MIME Type)
nouns http://www.onlamp.com
ver
bs
GET, P
OST, P
UT, DEL
ETE
content typesYAML, XML, JSON, etc.
![Page 28: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/28.jpg)
REST Web Services
![Page 29: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/29.jpg)
REST Web Services
CRUD
![Page 30: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/30.jpg)
REST Web Services
CRUD
Create
![Page 31: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/31.jpg)
REST Web Services
CRUD
Create
Read
![Page 32: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/32.jpg)
REST Web Services
CRUD
Create
Read
Update
![Page 33: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/33.jpg)
REST Web Services
CRUD
Create
Read
Update
Delete
![Page 34: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/34.jpg)
REST Web Services
• Treat your data like a static web page CRUD
Create
Read
Update
Delete
![Page 35: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/35.jpg)
REST Web Services
• Treat your data like a static web page
• Add data by POSTing a web page
CRUD
Create
Read
Update
Delete
![Page 36: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/36.jpg)
REST Web Services
• Treat your data like a static web page
• Add data by POSTing a web page
• Fetch data by GETting a web pageCRUD
Create
Read
Update
Delete
![Page 37: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/37.jpg)
REST Web Services
• Treat your data like a static web page
• Add data by POSTing a web page
• Fetch data by GETting a web page
• Update data by PUTing a web page
CRUD
Create
Read
Update
Delete
![Page 38: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/38.jpg)
REST Web Services
• Treat your data like a static web page
• Add data by POSTing a web page
• Fetch data by GETting a web page
• Update data by PUTing a web page
• Delete data by DELETing a web page
CRUD
Create
Read
Update
Delete
![Page 39: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/39.jpg)
REST Web Services
• Treat your data like a static web page
• Add data by POSTing a web page
• Fetch data by GETting a web page
• Update data by PUTing a web page
• Delete data by DELETing a web page
• E... it’s missing and it bugs me...
CRUD
Create
Read
Update
Delete
![Page 40: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/40.jpg)
Who Uses It
![Page 41: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/41.jpg)
Who Uses It
• Yahoo!
• Amazon
• Intuit
• Best Practical
• Socialtext
• Digg
• eBay
• Technorati
• Too many others to mention...
![Page 42: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/42.jpg)
What about other stuff?
![Page 43: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/43.jpg)
• RPC is a square peg
What about other stuff?
![Page 44: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/44.jpg)
• RPC is a square peg
• REST is round hole
What about other stuff?
![Page 45: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/45.jpg)
• RPC is a square peg
• REST is round hole
What about other stuff?
![Page 46: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/46.jpg)
• RPC is a square peg
• REST is round hole
• But it works!
What about other stuff?
![Page 47: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/47.jpg)
• RPC is a square peg
• REST is round hole
• But it works!
• Getting Info? GET
What about other stuff?
![Page 48: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/48.jpg)
• RPC is a square peg
• REST is round hole
• But it works!
• Getting Info? GET
• Modifying Something? POST
What about other stuff?
![Page 49: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/49.jpg)
• RPC is a square peg
• REST is round hole
• But it works!
• Getting Info? GET
• Modifying Something? POST
• Both? Not sure? POST
What about other stuff?
![Page 50: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/50.jpg)
ENOUGH BASICS. LET’S DO SOMETHING.
![Page 51: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/51.jpg)
# Manage your books from the command-line. Woo-hoo!% ./book list
![Page 52: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/52.jpg)
# Manage your books from the command-line. Woo-hoo!% ./book list0-8024-8160-4: .../library.cgi/=/model/book/id/0-8024-8160-40-85151-760-9: .../library.cgi/=/model/book/id/0-85151-760-90-936083-11-5: .../library.cgi/=/model/book/id/0-936083-11-5
![Page 53: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/53.jpg)
% ./book read 0-8024-8160-4
![Page 54: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/54.jpg)
---author: David Clotfeltercity: Chicagoid: 0-8024-8160-4isbn: 0-8024-8160-4publisher: Moody Publisherstitle: > Sinners in the Hands of a Good God: Reconciling Divine Judgment and Mercy'year: 2004
% ./book read 0-8024-8160-4
![Page 55: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/55.jpg)
![Page 56: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/56.jpg)
% ./book create reformation.yml
![Page 57: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/57.jpg)
% ./book create reformation.yml0-87552-183-5: .../library.cgi/=/model/book/id/0-87552-183-5
![Page 58: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/58.jpg)
% ./book create reformation.yml0-87552-183-5: .../library.cgi/=/model/book/id/0-87552-183-5
% ./book update 0-87552-183-5 reformation2.yml
![Page 59: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/59.jpg)
% ./book create reformation.yml0-87552-183-5: .../library.cgi/=/model/book/id/0-87552-183-5
% ./book update 0-87552-183-5 reformation2.ymlUpdated 0-87552-183-5
![Page 60: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/60.jpg)
% ./book create reformation.yml0-87552-183-5: .../library.cgi/=/model/book/id/0-87552-183-5
% ./book update 0-87552-183-5 reformation2.ymlUpdated 0-87552-183-5
% ./book delete 0-87552-183-5
![Page 61: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/61.jpg)
Deleted 0-87552-183-5
% ./book create reformation.yml0-87552-183-5: .../library.cgi/=/model/book/id/0-87552-183-5
% ./book update 0-87552-183-5 reformation2.ymlUpdated 0-87552-183-5
% ./book delete 0-87552-183-5
![Page 62: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/62.jpg)
Okay... But what did that do?
Putting it together
![Page 63: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/63.jpg)
Explaining the Nouns (a.k.a. URLs)
![Page 64: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/64.jpg)
Explaining the Nouns (a.k.a. URLs)
Scheme Borrowed from Jifty
![Page 65: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/65.jpg)
Explaining the Nouns (a.k.a. URLs)
What Example Why?
Prefix /= Marker for REST
Kind of Thing /=/model More Kinds
Name of Thing /=/model/book More Models
Field of Thing /=/model/book/id Multiple Identifiers
Value of Field /=/mode/book/id/1 Multiple Things
Scheme Borrowed from Jifty
![Page 66: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/66.jpg)
Explaining the Nouns (a.k.a. URLs)
What Example Why?
Prefix /= Marker for REST
Kind of Thing /=/model More Kinds
Name of Thing /=/model/book More Models
Field of Thing /=/model/book/id Multiple Identifiers
Value of Field /=/mode/book/id/1 Multiple Things
Scheme Borrowed from Jifty
![Page 67: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/67.jpg)
Explaining the Nouns (a.k.a. URLs)
What Example Why?
Prefix /= Marker for REST
Kind of Thing /=/model More Kinds
Name of Thing /=/model/book More Models
Field of Thing /=/model/book/id Multiple Identifiers
Value of Field /=/mode/book/id/1 Multiple Things
Scheme Borrowed from Jifty
![Page 68: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/68.jpg)
Explaining the Nouns (a.k.a. URLs)
What Example Why?
Prefix /= Marker for REST
Kind of Thing /=/model More Kinds
Name of Thing /=/model/book More Models
Field of Thing /=/model/book/id Multiple Identifiers
Value of Field /=/mode/book/id/1 Multiple Things
Scheme Borrowed from Jifty
![Page 69: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/69.jpg)
Explaining the Nouns (a.k.a. URLs)
What Example Why?
Prefix /= Marker for REST
Kind of Thing /=/model More Kinds
Name of Thing /=/model/book More Models
Field of Thing /=/model/book/id Multiple Identifiers
Value of Field /=/mode/book/id/1 Multiple Things
Scheme Borrowed from Jifty
![Page 70: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/70.jpg)
Explaining the Nouns (a.k.a. URLs)
What Example Why?
Prefix /= Marker for REST
Kind of Thing /=/model More Kinds
Name of Thing /=/model/book More Models
Field of Thing /=/model/book/id Multiple Identifiers
Value of Field /=/mode/book/id/1 Multiple Things
Scheme Borrowed from Jifty
![Page 71: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/71.jpg)
# book list - lists all the books the server returnssubcommand 'list' => sub {
# GET /=/model/book my $response = $ua->request(GET HOST.'/=/model/book/id');
# On success, find the link and print them out if ($response->is_success) { my @links = $response->content =~ /\bhref="([^"]+)"/gm; for my $url (@links) { my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; } }
# On failure, barf else { barf $response; }};
Read (List)
![Page 72: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/72.jpg)
# book list - lists all the books the server returnssubcommand 'list' => sub {
# GET /=/model/book my $response = $ua->request(GET HOST.'/=/model/book/id');
# On success, find the link and print them out if ($response->is_success) { my @links = $response->content =~ /\bhref="([^"]+)"/gm; for my $url (@links) { my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; } }
# On failure, barf else { barf $response; }};
Read (List)
![Page 73: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/73.jpg)
# book list - lists all the books the server returnssubcommand 'list' => sub {
# GET /=/model/book my $response = $ua->request(GET HOST.'/=/model/book/id');
# On success, find the link and print them out if ($response->is_success) { my @links = $response->content =~ /\bhref="([^"]+)"/gm; for my $url (@links) { my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; } }
# On failure, barf else { barf $response; }};
Read (List)
![Page 74: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/74.jpg)
# book list - lists all the books the server returnssubcommand 'list' => sub {
# GET /=/model/book my $response = $ua->request(GET HOST.'/=/model/book/id');
# On success, find the link and print them out if ($response->is_success) { my @links = $response->content =~ /\bhref="([^"]+)"/gm; for my $url (@links) { my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; } }
# On failure, barf else { barf $response; }};
Read (List)
![Page 75: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/75.jpg)
# book list - lists all the books the server returnssubcommand 'list' => sub {
# GET /=/model/book my $response = $ua->request(GET HOST.'/=/model/book/id');
# On success, find the link and print them out if ($response->is_success) { my @links = $response->content =~ /\bhref="([^"]+)"/gm; for my $url (@links) { my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; } }
# On failure, barf else { barf $response; }};
Read (List)
![Page 76: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/76.jpg)
# Get a whole list of available documentsGET qr{^/=/model/book/id$} => sub { print $q->header('text/html');
# Find all the files available my @items; for my $filename (glob get_local_path('*')) { my ($id) = $filename =~ m{([\d-]+)$}; next unless defined $id;
push @items, $q->li( $q->a({ href => absolute_url('/=/model/book/id/'.$id) }, $id), ); }
# List the items print $q->ul( @items);};
Read (List)
![Page 77: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/77.jpg)
# Get a whole list of available documentsGET qr{^/=/model/book/id$} => sub { print $q->header('text/html');
# Find all the files available my @items; for my $filename (glob get_local_path('*')) { my ($id) = $filename =~ m{([\d-]+)$}; next unless defined $id;
push @items, $q->li( $q->a({ href => absolute_url('/=/model/book/id/'.$id) }, $id), ); }
# List the items print $q->ul( @items);};
Read (List)
![Page 78: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/78.jpg)
# Get a whole list of available documentsGET qr{^/=/model/book/id$} => sub { print $q->header('text/html');
# Find all the files available my @items; for my $filename (glob get_local_path('*')) { my ($id) = $filename =~ m{([\d-]+)$}; next unless defined $id;
push @items, $q->li( $q->a({ href => absolute_url('/=/model/book/id/'.$id) }, $id), ); }
# List the items print $q->ul( @items);};
Read (List)
![Page 79: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/79.jpg)
# Get a whole list of available documentsGET qr{^/=/model/book/id$} => sub { print $q->header('text/html');
# Find all the files available my @items; for my $filename (glob get_local_path('*')) { my ($id) = $filename =~ m{([\d-]+)$}; next unless defined $id;
push @items, $q->li( $q->a({ href => absolute_url('/=/model/book/id/'.$id) }, $id), ); }
# List the items print $q->ul( @items);};
Read (List)
![Page 80: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/80.jpg)
# Get a whole list of available documentsGET qr{^/=/model/book/id$} => sub { print $q->header('text/html');
# Find all the files available my @items; for my $filename (glob get_local_path('*')) { my ($id) = $filename =~ m{([\d-]+)$}; next unless defined $id;
push @items, $q->li( $q->a({ href => absolute_url('/=/model/book/id/'.$id) }, $id), ); }
# List the items print $q->ul( @items);};
Read (List)
![Page 81: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/81.jpg)
# book read <id> - reads the book file for <id>subcommand 'read' => sub { my $id = shift @ARGV;
# GET /=/model/book/id/[id] my $response = $ua->request(GET HOST.'/=/model/book/id/'
.$id);
# On success, print the file if ($response->is_success) { print $response->content; }
# On failure, barf else { barf $response; }};
Read (Single)
![Page 82: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/82.jpg)
# book read <id> - reads the book file for <id>subcommand 'read' => sub { my $id = shift @ARGV;
# GET /=/model/book/id/[id] my $response = $ua->request(GET HOST.'/=/model/book/id/'
.$id);
# On success, print the file if ($response->is_success) { print $response->content; }
# On failure, barf else { barf $response; }};
Read (Single)
![Page 83: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/83.jpg)
# book read <id> - reads the book file for <id>subcommand 'read' => sub { my $id = shift @ARGV;
# GET /=/model/book/id/[id] my $response = $ua->request(GET HOST.'/=/model/book/id/'
.$id);
# On success, print the file if ($response->is_success) { print $response->content; }
# On failure, barf else { barf $response; }};
Read (Single)
![Page 84: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/84.jpg)
# book read <id> - reads the book file for <id>subcommand 'read' => sub { my $id = shift @ARGV;
# GET /=/model/book/id/[id] my $response = $ua->request(GET HOST.'/=/model/book/id/'
.$id);
# On success, print the file if ($response->is_success) { print $response->content; }
# On failure, barf else { barf $response; }};
Read (Single)
![Page 85: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/85.jpg)
# book read <id> - reads the book file for <id>subcommand 'read' => sub { my $id = shift @ARGV;
# GET /=/model/book/id/[id] my $response = $ua->request(GET HOST.'/=/model/book/id/'
.$id);
# On success, print the file if ($response->is_success) { print $response->content; }
# On failure, barf else { barf $response; }};
Read (Single)
![Page 86: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/86.jpg)
# Look up and read a resourceGET qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Look up the resource file my $filename = get_local_path($id); if (-f $filename) {
# Open and slurp up the file and output the resource open my $bookfh, $filename or barf 500, "I Am Broke", "Cannot open $filename: $!";
print $q->header('text/yaml'); print do { local $/; <$bookfh> }; }
# No such resource exists else{ barf 404, "Where is What?", "Book for $id does not exist."; }};
Read (Single)
![Page 87: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/87.jpg)
# Look up and read a resourceGET qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Look up the resource file my $filename = get_local_path($id); if (-f $filename) {
# Open and slurp up the file and output the resource open my $bookfh, $filename or barf 500, "I Am Broke", "Cannot open $filename: $!";
print $q->header('text/yaml'); print do { local $/; <$bookfh> }; }
# No such resource exists else{ barf 404, "Where is What?", "Book for $id does not exist."; }};
Read (Single)
![Page 88: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/88.jpg)
# Look up and read a resourceGET qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Look up the resource file my $filename = get_local_path($id); if (-f $filename) {
# Open and slurp up the file and output the resource open my $bookfh, $filename or barf 500, "I Am Broke", "Cannot open $filename: $!";
print $q->header('text/yaml'); print do { local $/; <$bookfh> }; }
# No such resource exists else{ barf 404, "Where is What?", "Book for $id does not exist."; }};
Read (Single)
![Page 89: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/89.jpg)
# Look up and read a resourceGET qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Look up the resource file my $filename = get_local_path($id); if (-f $filename) {
# Open and slurp up the file and output the resource open my $bookfh, $filename or barf 500, "I Am Broke", "Cannot open $filename: $!";
print $q->header('text/yaml'); print do { local $/; <$bookfh> }; }
# No such resource exists else{ barf 404, "Where is What?", "Book for $id does not exist."; }};
Read (Single)
![Page 90: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/90.jpg)
# Look up and read a resourceGET qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Look up the resource file my $filename = get_local_path($id); if (-f $filename) {
# Open and slurp up the file and output the resource open my $bookfh, $filename or barf 500, "I Am Broke", "Cannot open $filename: $!";
print $q->header('text/yaml'); print do { local $/; <$bookfh> }; }
# No such resource exists else{ barf 404, "Where is What?", "Book for $id does not exist."; }};
Read (Single)
![Page 91: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/91.jpg)
# Look up and read a resourceGET qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Look up the resource file my $filename = get_local_path($id); if (-f $filename) {
# Open and slurp up the file and output the resource open my $bookfh, $filename or barf 500, "I Am Broke", "Cannot open $filename: $!";
print $q->header('text/yaml'); print do { local $/; <$bookfh> }; }
# No such resource exists else{ barf 404, "Where is What?", "Book for $id does not exist."; }};
Read (Single)
![Page 92: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/92.jpg)
# book create <filename> - submits the book file in <filename> to the serversubcommand 'create' => sub { my $file = shift @ARGV;
# Slurp up the contents of the given filename my $book_data = slurp $file;
# POST /=/model/book my $response = $ua->request(POST HOST.'/=/model/book', 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, return the new ID assigned to the resource if ($response->is_success) { my $url = $response->header('Location'); my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; }
# On failure, barf else { barf $response; }};
Create
![Page 93: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/93.jpg)
# book create <filename> - submits the book file in <filename> to the serversubcommand 'create' => sub { my $file = shift @ARGV;
# Slurp up the contents of the given filename my $book_data = slurp $file;
# POST /=/model/book my $response = $ua->request(POST HOST.'/=/model/book', 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, return the new ID assigned to the resource if ($response->is_success) { my $url = $response->header('Location'); my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; }
# On failure, barf else { barf $response; }};
Create
![Page 94: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/94.jpg)
# book create <filename> - submits the book file in <filename> to the serversubcommand 'create' => sub { my $file = shift @ARGV;
# Slurp up the contents of the given filename my $book_data = slurp $file;
# POST /=/model/book my $response = $ua->request(POST HOST.'/=/model/book', 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, return the new ID assigned to the resource if ($response->is_success) { my $url = $response->header('Location'); my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; }
# On failure, barf else { barf $response; }};
Create
![Page 95: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/95.jpg)
# book create <filename> - submits the book file in <filename> to the serversubcommand 'create' => sub { my $file = shift @ARGV;
# Slurp up the contents of the given filename my $book_data = slurp $file;
# POST /=/model/book my $response = $ua->request(POST HOST.'/=/model/book', 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, return the new ID assigned to the resource if ($response->is_success) { my $url = $response->header('Location'); my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; }
# On failure, barf else { barf $response; }};
Create
![Page 96: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/96.jpg)
# book create <filename> - submits the book file in <filename> to the serversubcommand 'create' => sub { my $file = shift @ARGV;
# Slurp up the contents of the given filename my $book_data = slurp $file;
# POST /=/model/book my $response = $ua->request(POST HOST.'/=/model/book', 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, return the new ID assigned to the resource if ($response->is_success) { my $url = $response->header('Location'); my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; }
# On failure, barf else { barf $response; }};
Create
![Page 97: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/97.jpg)
# book create <filename> - submits the book file in <filename> to the serversubcommand 'create' => sub { my $file = shift @ARGV;
# Slurp up the contents of the given filename my $book_data = slurp $file;
# POST /=/model/book my $response = $ua->request(POST HOST.'/=/model/book', 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, return the new ID assigned to the resource if ($response->is_success) { my $url = $response->header('Location'); my ($id) = $url =~ /([\d-]+)$/; print "$id: $url\n"; }
# On failure, barf else { barf $response; }};
Create
![Page 98: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/98.jpg)
# Handle the creation of new booksPOST qr{^/=/model/book$} => sub {
# Check to make sure the input book is sane my $book= check_book( $q->param('POSTDATA') );
# If we have an ISBN (some books don't!), then die if we already have # it because we don't permit POST cannot for updates! if ($book->{isbn} and -f get_local_path($book->{isbn})) { barf 500, 'Not Gonna Do It', 'A POST may not be used to update an existing book.'; }
# Our data is sane!
# ...
Create (part 1)
![Page 99: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/99.jpg)
# Handle the creation of new booksPOST qr{^/=/model/book$} => sub {
# Check to make sure the input book is sane my $book= check_book( $q->param('POSTDATA') );
# If we have an ISBN (some books don't!), then die if we already have # it because we don't permit POST cannot for updates! if ($book->{isbn} and -f get_local_path($book->{isbn})) { barf 500, 'Not Gonna Do It', 'A POST may not be used to update an existing book.'; }
# Our data is sane!
# ...
Create (part 1)
![Page 100: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/100.jpg)
# Handle the creation of new booksPOST qr{^/=/model/book$} => sub {
# Check to make sure the input book is sane my $book= check_book( $q->param('POSTDATA') );
# If we have an ISBN (some books don't!), then die if we already have # it because we don't permit POST cannot for updates! if ($book->{isbn} and -f get_local_path($book->{isbn})) { barf 500, 'Not Gonna Do It', 'A POST may not be used to update an existing book.'; }
# Our data is sane!
# ...
Create (part 1)
![Page 101: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/101.jpg)
# Handle the creation of new booksPOST qr{^/=/model/book$} => sub {
# Check to make sure the input book is sane my $book= check_book( $q->param('POSTDATA') );
# If we have an ISBN (some books don't!), then die if we already have # it because we don't permit POST cannot for updates! if ($book->{isbn} and -f get_local_path($book->{isbn})) { barf 500, 'Not Gonna Do It', 'A POST may not be used to update an existing book.'; }
# Our data is sane!
# ...
Create (part 1)
![Page 102: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/102.jpg)
# Handle the creation of new booksPOST qr{^/=/model/book$} => sub {
# Check to make sure the input book is sane my $book= check_book( $q->param('POSTDATA') );
# If we have an ISBN (some books don't!), then die if we already have # it because we don't permit POST cannot for updates! if ($book->{isbn} and -f get_local_path($book->{isbn})) { barf 500, 'Not Gonna Do It', 'A POST may not be used to update an existing book.'; }
# Our data is sane!
# ...
Create (part 1)
![Page 103: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/103.jpg)
# Handle the creation of new booksPOST qr{^/=/model/book$} => sub {
# Check to make sure the input book is sane my $book= check_book( $q->param('POSTDATA') );
# If we have an ISBN (some books don't!), then die if we already have # it because we don't permit POST cannot for updates! if ($book->{isbn} and -f get_local_path($book->{isbn})) { barf 500, 'Not Gonna Do It', 'A POST may not be used to update an existing book.'; }
# Our data is sane!
# ...
Create (part 1)
![Page 104: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/104.jpg)
# ...
# Figure out an ID, this is either the ISBN or a generated ID my $id = $book->{isbn} ? $book->{isbn} : next_id;
# Store the ID for reference within the record $book->{id} = $id;
# Save the resource eval { YAML::DumpFile(get_local_path($id), $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user my $resource_url = absolute_url('/=/model/book/id/'.$id); print $q->header( -status => 201, -type => 'text/html', -location => $resource_url, ); print $q->h1("Created $book->{title}"); print $q->ul( $q->li( $q->a({ href => $resource_url }, $resource_url) ) );};
Create (part 2)
![Page 105: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/105.jpg)
# ...
# Figure out an ID, this is either the ISBN or a generated ID my $id = $book->{isbn} ? $book->{isbn} : next_id;
# Store the ID for reference within the record $book->{id} = $id;
# Save the resource eval { YAML::DumpFile(get_local_path($id), $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user my $resource_url = absolute_url('/=/model/book/id/'.$id); print $q->header( -status => 201, -type => 'text/html', -location => $resource_url, ); print $q->h1("Created $book->{title}"); print $q->ul( $q->li( $q->a({ href => $resource_url }, $resource_url) ) );};
Create (part 2)
![Page 106: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/106.jpg)
# ...
# Figure out an ID, this is either the ISBN or a generated ID my $id = $book->{isbn} ? $book->{isbn} : next_id;
# Store the ID for reference within the record $book->{id} = $id;
# Save the resource eval { YAML::DumpFile(get_local_path($id), $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user my $resource_url = absolute_url('/=/model/book/id/'.$id); print $q->header( -status => 201, -type => 'text/html', -location => $resource_url, ); print $q->h1("Created $book->{title}"); print $q->ul( $q->li( $q->a({ href => $resource_url }, $resource_url) ) );};
Create (part 2)
![Page 107: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/107.jpg)
# ...
# Figure out an ID, this is either the ISBN or a generated ID my $id = $book->{isbn} ? $book->{isbn} : next_id;
# Store the ID for reference within the record $book->{id} = $id;
# Save the resource eval { YAML::DumpFile(get_local_path($id), $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user my $resource_url = absolute_url('/=/model/book/id/'.$id); print $q->header( -status => 201, -type => 'text/html', -location => $resource_url, ); print $q->h1("Created $book->{title}"); print $q->ul( $q->li( $q->a({ href => $resource_url }, $resource_url) ) );};
Create (part 2)
![Page 108: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/108.jpg)
# ...
# Figure out an ID, this is either the ISBN or a generated ID my $id = $book->{isbn} ? $book->{isbn} : next_id;
# Store the ID for reference within the record $book->{id} = $id;
# Save the resource eval { YAML::DumpFile(get_local_path($id), $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user my $resource_url = absolute_url('/=/model/book/id/'.$id); print $q->header( -status => 201, -type => 'text/html', -location => $resource_url, ); print $q->h1("Created $book->{title}"); print $q->ul( $q->li( $q->a({ href => $resource_url }, $resource_url) ) );};
Create (part 2)
![Page 109: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/109.jpg)
# book update <id> <filename> - updates the book file <id> using <filename>subcommand 'update' => sub { my $id = shift @ARGV; my $file = shift @ARGV;
# Slurp up the given file name my $book_data = slurp $file;
# PUT /=/model/book/id/[id] my $response = $ua->request(PUT HOST.'/=/model/book/id/'.$id, 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, just announce success if ($response->is_success) { print "Updated $id\n"; }
# On failure, barf else { barf $response; }};
Update
![Page 110: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/110.jpg)
# book update <id> <filename> - updates the book file <id> using <filename>subcommand 'update' => sub { my $id = shift @ARGV; my $file = shift @ARGV;
# Slurp up the given file name my $book_data = slurp $file;
# PUT /=/model/book/id/[id] my $response = $ua->request(PUT HOST.'/=/model/book/id/'.$id, 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, just announce success if ($response->is_success) { print "Updated $id\n"; }
# On failure, barf else { barf $response; }};
Update
![Page 111: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/111.jpg)
# book update <id> <filename> - updates the book file <id> using <filename>subcommand 'update' => sub { my $id = shift @ARGV; my $file = shift @ARGV;
# Slurp up the given file name my $book_data = slurp $file;
# PUT /=/model/book/id/[id] my $response = $ua->request(PUT HOST.'/=/model/book/id/'.$id, 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, just announce success if ($response->is_success) { print "Updated $id\n"; }
# On failure, barf else { barf $response; }};
Update
![Page 112: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/112.jpg)
# book update <id> <filename> - updates the book file <id> using <filename>subcommand 'update' => sub { my $id = shift @ARGV; my $file = shift @ARGV;
# Slurp up the given file name my $book_data = slurp $file;
# PUT /=/model/book/id/[id] my $response = $ua->request(PUT HOST.'/=/model/book/id/'.$id, 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, just announce success if ($response->is_success) { print "Updated $id\n"; }
# On failure, barf else { barf $response; }};
Update
![Page 113: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/113.jpg)
# book update <id> <filename> - updates the book file <id> using <filename>subcommand 'update' => sub { my $id = shift @ARGV; my $file = shift @ARGV;
# Slurp up the given file name my $book_data = slurp $file;
# PUT /=/model/book/id/[id] my $response = $ua->request(PUT HOST.'/=/model/book/id/'.$id, 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, just announce success if ($response->is_success) { print "Updated $id\n"; }
# On failure, barf else { barf $response; }};
Update
![Page 114: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/114.jpg)
# book update <id> <filename> - updates the book file <id> using <filename>subcommand 'update' => sub { my $id = shift @ARGV; my $file = shift @ARGV;
# Slurp up the given file name my $book_data = slurp $file;
# PUT /=/model/book/id/[id] my $response = $ua->request(PUT HOST.'/=/model/book/id/'.$id, 'Content-Type' => 'text/yaml', Content => $book_data, );
# On success, just announce success if ($response->is_success) { print "Updated $id\n"; }
# On failure, barf else { barf $response; }};
Update
![Page 115: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/115.jpg)
# Handle updates to booksPUT qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Check to make sure the input book is sane my $book = check_book( $q->param('PUTDATA') );
# Make sure the book already exists or barf my $resource_path= get_local_path($id); unless(-f $resource_path) { barf 500, 'Not Gonna Do It', 'Cannot use PUTs for creating a new resource.'; }
# Make sure the ID is set $book->{id} = $id;
# Save the resource eval { YAML::DumpFile($resource_path, $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user print $q->header('text/html'); print $q->h1("Updated $book->{title}");};
Update
![Page 116: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/116.jpg)
# Handle updates to booksPUT qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Check to make sure the input book is sane my $book = check_book( $q->param('PUTDATA') );
# Make sure the book already exists or barf my $resource_path= get_local_path($id); unless(-f $resource_path) { barf 500, 'Not Gonna Do It', 'Cannot use PUTs for creating a new resource.'; }
# Make sure the ID is set $book->{id} = $id;
# Save the resource eval { YAML::DumpFile($resource_path, $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user print $q->header('text/html'); print $q->h1("Updated $book->{title}");};
Update
![Page 117: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/117.jpg)
# Handle updates to booksPUT qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Check to make sure the input book is sane my $book = check_book( $q->param('PUTDATA') );
# Make sure the book already exists or barf my $resource_path= get_local_path($id); unless(-f $resource_path) { barf 500, 'Not Gonna Do It', 'Cannot use PUTs for creating a new resource.'; }
# Make sure the ID is set $book->{id} = $id;
# Save the resource eval { YAML::DumpFile($resource_path, $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user print $q->header('text/html'); print $q->h1("Updated $book->{title}");};
Update
![Page 118: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/118.jpg)
# Handle updates to booksPUT qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Check to make sure the input book is sane my $book = check_book( $q->param('PUTDATA') );
# Make sure the book already exists or barf my $resource_path= get_local_path($id); unless(-f $resource_path) { barf 500, 'Not Gonna Do It', 'Cannot use PUTs for creating a new resource.'; }
# Make sure the ID is set $book->{id} = $id;
# Save the resource eval { YAML::DumpFile($resource_path, $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user print $q->header('text/html'); print $q->h1("Updated $book->{title}");};
Update
![Page 119: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/119.jpg)
# Handle updates to booksPUT qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Check to make sure the input book is sane my $book = check_book( $q->param('PUTDATA') );
# Make sure the book already exists or barf my $resource_path= get_local_path($id); unless(-f $resource_path) { barf 500, 'Not Gonna Do It', 'Cannot use PUTs for creating a new resource.'; }
# Make sure the ID is set $book->{id} = $id;
# Save the resource eval { YAML::DumpFile($resource_path, $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user print $q->header('text/html'); print $q->h1("Updated $book->{title}");};
Update
![Page 120: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/120.jpg)
# Handle updates to booksPUT qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Check to make sure the input book is sane my $book = check_book( $q->param('PUTDATA') );
# Make sure the book already exists or barf my $resource_path= get_local_path($id); unless(-f $resource_path) { barf 500, 'Not Gonna Do It', 'Cannot use PUTs for creating a new resource.'; }
# Make sure the ID is set $book->{id} = $id;
# Save the resource eval { YAML::DumpFile($resource_path, $book) }; barf 500, 'I Am Broke', $@ if $@;
# Note the success to the end-user print $q->header('text/html'); print $q->h1("Updated $book->{title}");};
Update
![Page 121: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/121.jpg)
# book delete <id> - deletes the book resource with ID <id>subcommand 'delete' => sub { my $id = shift @ARGV;
# DELETE /=/model/book/id/[id] my $response = $ua->request( HTTP::Request->new( DELETE => HOST.'/=/model/book/id/'.$id) );
# On success, announce it if ($response->is_success) { print "Deleted $id\n"; }
# On failure, barf else { barf $response; }};
Delete
![Page 122: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/122.jpg)
# book delete <id> - deletes the book resource with ID <id>subcommand 'delete' => sub { my $id = shift @ARGV;
# DELETE /=/model/book/id/[id] my $response = $ua->request( HTTP::Request->new( DELETE => HOST.'/=/model/book/id/'.$id) );
# On success, announce it if ($response->is_success) { print "Deleted $id\n"; }
# On failure, barf else { barf $response; }};
Delete
![Page 123: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/123.jpg)
# book delete <id> - deletes the book resource with ID <id>subcommand 'delete' => sub { my $id = shift @ARGV;
# DELETE /=/model/book/id/[id] my $response = $ua->request( HTTP::Request->new( DELETE => HOST.'/=/model/book/id/'.$id) );
# On success, announce it if ($response->is_success) { print "Deleted $id\n"; }
# On failure, barf else { barf $response; }};
Delete
![Page 124: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/124.jpg)
# book delete <id> - deletes the book resource with ID <id>subcommand 'delete' => sub { my $id = shift @ARGV;
# DELETE /=/model/book/id/[id] my $response = $ua->request( HTTP::Request->new( DELETE => HOST.'/=/model/book/id/'.$id) );
# On success, announce it if ($response->is_success) { print "Deleted $id\n"; }
# On failure, barf else { barf $response; }};
Delete
![Page 125: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/125.jpg)
# book delete <id> - deletes the book resource with ID <id>subcommand 'delete' => sub { my $id = shift @ARGV;
# DELETE /=/model/book/id/[id] my $response = $ua->request( HTTP::Request->new( DELETE => HOST.'/=/model/book/id/'.$id) );
# On success, announce it if ($response->is_success) { print "Deleted $id\n"; }
# On failure, barf else { barf $response; }};
Delete
![Page 126: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/126.jpg)
DELETE qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Make sure the book actually exists my $resource_path = get_local_path($id); unless (-f $resource_path) { barf 404, 'Where is What?', 'Nothing here to delete.'; }
# Baleted! unlink $resource_path;
# Tell me about it. print $q->header('text/html'); print $q->h1("Deleted $id");};
Delete
![Page 127: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/127.jpg)
DELETE qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Make sure the book actually exists my $resource_path = get_local_path($id); unless (-f $resource_path) { barf 404, 'Where is What?', 'Nothing here to delete.'; }
# Baleted! unlink $resource_path;
# Tell me about it. print $q->header('text/html'); print $q->h1("Deleted $id");};
Delete
![Page 128: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/128.jpg)
DELETE qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Make sure the book actually exists my $resource_path = get_local_path($id); unless (-f $resource_path) { barf 404, 'Where is What?', 'Nothing here to delete.'; }
# Baleted! unlink $resource_path;
# Tell me about it. print $q->header('text/html'); print $q->h1("Deleted $id");};
Delete
![Page 129: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/129.jpg)
DELETE qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Make sure the book actually exists my $resource_path = get_local_path($id); unless (-f $resource_path) { barf 404, 'Where is What?', 'Nothing here to delete.'; }
# Baleted! unlink $resource_path;
# Tell me about it. print $q->header('text/html'); print $q->h1("Deleted $id");};
Delete
![Page 130: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/130.jpg)
DELETE qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Make sure the book actually exists my $resource_path = get_local_path($id); unless (-f $resource_path) { barf 404, 'Where is What?', 'Nothing here to delete.'; }
# Baleted! unlink $resource_path;
# Tell me about it. print $q->header('text/html'); print $q->h1("Deleted $id");};
Delete
![Page 131: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/131.jpg)
DELETE qr{^/=/model/book/id/([\d-]+)$} => sub { my $id= $1;
# Make sure the book actually exists my $resource_path = get_local_path($id); unless (-f $resource_path) { barf 404, 'Where is What?', 'Nothing here to delete.'; }
# Baleted! unlink $resource_path;
# Tell me about it. print $q->header('text/html'); print $q->h1("Deleted $id");};
Delete
![Page 132: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/132.jpg)
# Provide some nice documentationGET qr{^/=$} => sub { print $q->header('text/html');
print $q->h1('REST API Documentation');
print $q->p('Here is a list of what you can do:');
print $q->dl( $q->dt('GET /=/model/book/id'), $q->dd('Returns a list of available book IDs.'),
$q->dt('GET /=/model/book/id/[ID]'), $q->dd('ID may be a number or the ISBN. Returns the book.'),
$q->dt('POST /=/model/book'), $q->dd('Create a new book record. Returns the new URL to fetch with.'),
$q->dt('PUT /=/model/book/id/[ID]'), $q->dd('Update a book by posting a complete book file.'),
$q->dt('DELETE /=/model/book/id/[ID]'), $q->dd('Delete a book.'), );
print $q->p('All book resources are stored or fetched in YAML format. The list of books will be fetched in HTML with each LI in the returned listing containing a link to a book resource.');
print $q->p('Here is a sample book. The "title" field is the only required field for books. The "isbn" field should be equal to the "id" field, if the "isbn" is present. The "id" field should be the [ID] used to fetch, updated, or delete the record.');
print $q->pre(q{isbn: 0-7852-1155-1title: "The New Strong's Exhaustive Concordance of the Bible"author: James Strong, LL.D., S.T.D.publisher: Thomas Nelson Publisherscity: Nashville, Tennesseeyear: 1995});};
Built-in Documentation
![Page 133: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/133.jpg)
• Use whatever content types are most appropriate to your audience: XML, YAML, JSON, HTML, RSS/Atom, SQL, CSV, vFiles, PDF
• Don’t be afraid to offer multiple formats using the Accept: headers or even file name suffixes
• Use the full range of HTTP response codes to give clear responses
• Include additional X-blah: headers for metadata
Exercises for the Audience
![Page 134: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/134.jpg)
Recommended Resources
• Sample Code:http://contentment.org/files/onlamp/library.cgihttp://contentment.org/files/onlamp/book
• Original Articles:http://www.onlamp.com/pub/a/onlamp/2008/02/19/developing-restful-web-services-in-perl.htmlhttp://contentment.org/2008/08/developing-restful-web-service.html
• OpenResty - Nice REST middleware server by Agent Zhang:http://search.cpan.org/dist/OpenResty/
• Jifty - I ripped off the style of the REST interface of Jifty for this demo:http://search.cpan.org/dist/Jifty/
• HTTP Specification: http://www.w3.org/Protocols/rfc2616/rfc2616.html
• REST Wiki: http://rest.blueoxen.net/
![Page 135: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/135.jpg)
![Page 136: Making Your Perl REST](https://reader034.vdocuments.us/reader034/viewer/2022052523/55583248d8b42acb078b460a/html5/thumbnails/136.jpg)
Thank you!