You are on page 1of 53

REST in Practice Part II

Centro de Informática Universidade Federal de Pernambuco

Vanilson Burégio
[www: vanilson.com] - [email: vaab@cin.ufpe.br ] August-2011

Part of this presentation was based on the high quality material gently provided by Dr. Jim Webber, author of the book “REST in Practice: Hypermedia and Systems Architecture”, for educational purposes.

2

Agenda
• Discussion
– Research Activity

• Tutorial
– REST with Java (JAX-RS) using Jersey

• Hypermedia and RESTFul Services

3

Research Activity

• Compare:
– REST Vs SOAP – REST Vs SOA – REST Vs WS-*

Tutorial: REST with Java (JAX-RS) using Jersey

xml" you will register a servlet provided by Jersey Open Source Reference Implementation for building RESTful Web services • also define the path under which your REST web application will be available http://your_domain:port/display-name/url-pattern/path_from_rest_class . REST and Jersey • JAX-RS (The Java API for RESTful Web Services) – Java standard REST support – Annotations to define the REST relevance of classes – In "web.Java.

IN1163 2011.2011.IN1163 2011.2 Multiple resource representations addressed by a single URI .IN1163 2011.2 title title resource http://localhost:8080/IN1163/rest/title HTML representation TEXT representation Social Machines IN1163 .2</title> <body><h1>Social Machines .2</h1> </body> </html> XML representation http://localhost:8080/IN1163/rest/title Social Machines .First example – simple resource • Defining a simple resource – accessing its different representations using HTTP Accept request header – Our URL pattern: /rest/* http://localhost:8080/IN1163/rest/title – TODO: • Modify “web.xml” • TitleResource.java <html> <title>Social Machines .

path(“…").create(config).accept(<MEDIA_TYPE>).resource(<BASE URI>).get(<type of the response>) • TODO: TitleClient.java .path(“…”). Client client = Client. – Send a GET • webResource. WebResource webResource = client.First example – simple resource • Defining na Application Client to manipulate the resource – Creating a web resource ClientConfig config = new DefaultClientConfig().

java – Test: http://localhost:8080/IN1163/rest/oneLesson .java – Analyse class: OneLessonResource.JAXB • Restful webservices and JAXB – JAX-RS supports the automatic creation of XML and JSON via JAXB • @XmlRootElement – TODO: Lesson.

java) – Create a new lesson from a HTML form • LessonsResource. Delete) restful web service • Existing class: LessonDao.java • TODO – List lessons on browser (LessonsResource.java) – Count lessons (LessonsResource.java – Delete a lesson • LessonsClient .html – Get an specific lesson (. Update. Read.CRUD (Create. /rest/lessons/1) • LessonResource • LessonsResource..java • create_lesson..

Hypermedia and RESTful Services .

Revisiting Resource Lifetime • On the Web. the lifecycle of a single resource is more than: – – – – Creation Updating Reading Deleting • Can also get metadata – About the resource – About its (subset of) the verbs it understands • And as we see. resources tell us about other resources we might want to interact with… .

Links • Connectedness is good in Web-based systems • Resource representations can contain other URIs • Links act as state transitions • Application (conversation) state is captured in terms of these states .

Describing Contracts with Links • The value of the Web is its “linked-ness” – Links on a Web page constitute a contractfor page traversals • The same is true of the programmatic Web • Use Links to describe state transitions in programmatic Web services – By navigating resources you change application state • Hypermedia formats support this – Allow us to describe higher-order protocols which sit comfortably atop HTTP – Hence application/vnd.restbucks+xml .

Links are State Transitions .

"> <link rel="payment" href="https://pay" type="application/xml"/> <link rel="postpone" href="https://wishlist" type="application/xml"/> </confirm> • Following a link causes an action to occur • This is the start of a state machine! • Links lead to other resources which also have links • Can make this stronger with semantics – Microformats ...Links as APIs <confirm xmlns=".

Richardson Model Level 3 • Lots of URIs that address resources • Embraces HTTP as an application protocol • Resource representations and formats identify other resources – Hypermedia at last! .

Protocol REST • “Protocol” REST – Focus on media types as contracts – Protocol state transitions – DAPs – Domain Application Protocols .

Workflow and MOM • With Web Services we exchange messages with the service • Resource state is hidden from view • Conversation state is all we know • Uniform interface. roles defined by SOAP – No “operations” – Advertise it with SSDL. BPEL Order Drink Add Specialities Order Confirmation Pay Coffee! .

no WADL – Media type defines processing model – Links (with microformats) describe state transitions • This is HATEOAS! • So let’s see how we order a coffee at Restbucks.Hypermedia Describes Protocols! • Links declare next valid steps • Following links and interacting with resources changes application state • Media types with links define contracts • Don’t need a static contract description – No WSDL.com/articles/webber-rest-workflow .com… – Based on: http://www.infoq.

Workflow • How does a typical enterprise workflow look when it’s implemented in a Web-friendly way? • Let’s take Restbucks ordering service as an example. the happy path is: – Make selection • Add any specialities – Pay – Wait for a while – Collect drink .

com/order/1234 Conclude the ordering process return latest representa on of the resource GET 2 4 3 cancelled preparing 5 ready 6 completed 1 payment expected .com/order/1234 h ps://restbucks.com/order h p://restbucks.com/receipt/1234 h p://restbucks.com/order/1234 h p://restbucks.com/payment/1234 new order (create resource) update order (only if state is at “payment expected”) order cancelled (only if state is at “payment expected”) Payment accepted POST DELETE PUT Barista prepared order DELETE h p://restbucks.Static Interface and State Transitions Transi ons ini ated by consuming applica ons POST Business logic Events causing state transi ons 1 2 3 4 5 6 h p://restbucks.

com/order Restbucks Service Client .Place an Order • POST to a well-known URI – http://restbucks.

com Connection: keep-alive Content-Length: 283 <?xml version="1.com"> <ns2:item> <ns2:milk>semi</ns2:milk> <ns2:size>large</ns2:size> <ns2:drink>latte</ns2:drink> </ns2:item> <ns2:location>takeaway</ns2:location> </ns2:order> .restbucks+xml Host: restbucks.Placing an Order • Request POST /order HTTP/1.restbucks+xml Accept: application/vnd.restbucks.1 Content-Type: application/vnd.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.

restbucks.com/cancel"/> <ns3:link mediaType="application/vnd.restbucks.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.com/order/1234" rel="http://relations.com" xmlns:ns3="http://schemas.1 201 Created server: grizzly/1.Placing an Order • Response HTTP/1. 03 Mar 2010 20:58:03 GMT <?xml version="1.0</ns2:cost> <ns2:status>unpaid</ns2:status> </ns2:order> .com/payment/1234" rel="http://relations.restbucks.com/dap"> <ns3:link mediaType="application/vnd.com/payment"/> <ns3:link mediaType="application/vnd.com/order/1234" rel="http://relations.restbucks+xml" uri="http://restbucks.com/update"/> <ns3:link mediaType="application/vnd.8.restbucks.com/order/1234" rel="self"/> <ns2:item> <ns2:milk>semi</ns2:milk> <ns2:size>large</ns2:size> <ns2:drink>latte</ns2:drink> </ns2:item> <ns2:location>takeaway</ns2:location> <ns2:cost>2.restbucks+xml" uri="http://restbucks.restbucks+xml Content-Length: 1039 Date: Wed.restbucks+xml" uri="http://restbucks.restbucks+xml" uri="http://restbucks.com/order/1234 Content-Type: application/vnd.1 Location: http://restbucks.restbucks.

com/order/1234 Client Restbucks Service .Confirm the Order • GET from the rel=“self” URI – http://restbucks.

com Connection: keep-alive .Confirm the Order • Request GET /order/1234 HTTP/1.1 Accept: application/vnd.restbucks+xml Host: restbucks.

com/payment"/> <ns3:link mediaType="application/vnd.restbucks.1 200 OK Location: http://restbucks.restbucks.com/order/1234" rel="self"/> <ns2:item> <ns2:milk>semi</ns2:milk> <ns2:size>large</ns2:size> <ns2:drink>latte</ns2:drink> </ns2:item> <ns2:location>takeaway</ns2:location> <ns2:cost>2.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.restbucks+xml Content-Length: 911 Date: Sun.com/update"/> <ns3:link mediaType="application/vnd.com/payment/1234" rel="http://relations.restbucks+xml" uri="http://restbucks.restbucks+xml" uri="http://restbucks.restbucks+xml" uri="http://restbucks.com/dap"> <ns3:link mediaType="application/vnd.restbucks.com/order/1234" rel="http://relations.restbucks.restbucks+xml" uri="http://restbucks. 06 Sep 2009 06:51:22 GMT <?xml version="1.com" xmlns:ns3="http://schemas.Confirm the Order • Response HTTP/1.restbucks.com/order/1234 Content-Type: application/vnd.com/order/1234" rel="http://relations.0</ns2:cost> <ns2:status>unpaid</ns2:status> </ns2:order> .com/cancel"/> <ns3:link mediaType="application/vnd.

com/order/f932f92d Client Restbucks Service .Change the Order • POST new order to service-generated URI – http://restbucks.

POST? Not PUT? • PUT expects the whole resource state to be presented in the request – But our clients aren’t responsible for generating cost or status elements • PATCH would be better – It allows us to send diffs. but isn’t part of the standard yet • So POST is our only option – Compare this to our CRUD protocol earlier .

restbucks.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.Change the Order • Request POST order/1234 HTTP/1.restbucks+xml Accept: application/vnd.1 Content-Type: application/vnd.com Connection: keep-alive Content-Length: 288 <?xml version="1.com"> <ns2:item> No service<ns2:milk>semi</ns2:milk> generated <ns2:size>large</ns2:size> content <ns2:drink>cappuccino</ns2:drink> </ns2:item> <ns2:location>takeaway</ns2:location> </ns2:order> .restbucks+xml Host: restbucks.

restbucks+xml" uri="http://restbucks.com/order/1234" rel="self"/> <ns2:item> <ns2:milk>semi</ns2:milk> <ns2:size>large</ns2:size> <ns2:drink>cappuccino</ns2:drink> </ns2:item> <ns2:location>takeaway</ns2:location> <ns2:cost>2.com/order/1234" rel="http://relations.restbucks. 06 Sep 2009 06:52:22 GMT <?xml version="1.restbucks+xml" uri="http://restbucks.0</ns2:cost> <ns2:status>unpaid</ns2:status> </ns2:order> .1 200 OK Location: http://restbucks.restbucks.restbucks.com/update"/> <ns3:link mediaType="application/vnd.Change the Order • Response HTTP/1.com" xmlns:ns3="http://schemas.com/payment"/> <ns3:link mediaType="application/vnd.restbucks.com/dap"> <ns3:link mediaType="application/vnd.com/payment/1234" rel="http://relations.restbucks+xml" uri="http://restbucks.restbucks+xml" uri="http://restbucks.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.restbucks.com/order/1234 Content-Type: application/vnd.com/cancel"/> <ns3:link mediaType="application/vnd.com/order/1234" rel="http://relations.restbucks+xml Content-Length: 916 Date: Sun.

Statelessness • Remember interactions with resources are stateless • The resource “forgets” about you while you’re not directly interacting with it • Which means race conditions are possible • Use If-Unmodified-Since on a timestamp to make sure • You’ll get a 412 PreconditionFailed if you lost the race – Or use If-Match and an ETag – But you’ll avoid potentially putting the resource into some inconsistent state .

1 Host: restbucks.Warning: Don’t be Slow! • Can only make changes until someone actually makes your drink – You’re safe if you use If-Unmodified-Since or If-Match – But resource state can change without you!  Request PUT /order/1234 HTTP 1.com  Response Allow: GET Too slow! Someone else has changed the state of my order .com ..  Response 409 Conflict  Request OPTIONS /order/1234 HTTP 1.1 Host: restbucks..

com/order/1234 Client Restbucks Service .What if we want to cancel? • DELETE order at order URI – http://restbucks.

1 Host: restbucks.restbucks+xml Date: Sun.What if we want to cancel? • Request DELETE /order/1234HTTP/1.1 200 OK Content-Type: application/vnd.com Connection: keep-alive • Response HTTP/1. 06 Sep 2009 06:53:22 GMT .

com/payment/1234 Client Restbucks Service .Order Payment • PUT to service-generated payment URI – http://restbucks.

prefer idempotent verbs .Why PUT this time? • It’s idempotent – Safe to repeat in the event of failures • For all $ transactions.

restbucks+xml Host: restbucks.0</amount> <cardholderName>Michael Farraday</cardholderName> <cardNumber>11223344</cardNumber> <expiryMonth>12</expiryMonth> <expiryYear>12</expiryYear> </payment> .restbucks+xml Accept: application/vnd.com"> <amount>2.0" encoding="UTF-8" standalone="yes"?> <payment xmlns="http://schemas.1 Content-Type: application/vnd.com Connection: keep-alive Content-Length: 287 <?xml version="1.restbucks.Order Payment • Request PUT /payment/1234 HTTP/1.

com/order"/> <link mediaType="application/vnd.restbucks+xml" uri="http://restbucks.com"> <link mediaType="application/vnd.com/payment/1234 Content-Type: application/vnd. 03 Mar 2010 20:58:03 GMT <?xml version="1.Order Payment • Response HTTP/1.restbucks+xml" uri="http://restbucks.com/order/1234" rel="http://relations.com/receipt/1234" rel="http://relations.com/receipt"/> <ns2:amount>2.1 201 Created server: grizzly/1.restbucks.0" encoding="UTF-8" standalone="yes"?> <ns2:payment xmlns="http://schemas.restbucks.0</ns2:amount> <ns2:cardholderName>Michael Farraday</ns2:cardholderName> <ns2:cardNumber>11223344</ns2:cardNumber> <ns2:expiryMonth>12</ns2:expiryMonth> <ns2:expiryYear>12</ns2:expiryYear> </ns2:payment> .restbucks+xml Content-Length: 650 Date: Wed.restbucks.8.com/dap" xmlns:ns2="http://schemas.restbucks.1 Location: http://restbucks.

What if we want to cancel now? • Request DELETE /order/1234 HTTP/1.com Connection: keep-alive • Response HTTP/1. 06 Sep 2009 07:43:29 GMT .1 405 Method Not Allowed Allow: GET Content-Type: application/vnd.restbucks+xml Content-Length: 0 Date: Sun.1 Host: restbucks.

Grab a Receipt • GET service-generated receipt URI – http://restbucks.com/receipt/1234 Client Restbucks Service .

restbucks+xml Host: restbucks.com .1 Accept: application/vnd.Grab a Receipt • Request GET /receipt/1234 HTTP/1.

restbucks+xml" uri="http://restbucks.1 200 OK server: grizzly/1.restbucks+xml Content-Length: 384 Date: Wed.0" encoding="UTF-8" standalone="yes"?> <ns2:receipt xmlns="http://schemas.834+01:00</ns2:paid> </ns2:receipt> .restbucks.com/order/1234" rel="http://relations.com/order"/> <ns2:amount>2.com/dap" xmlns:ns2="http://schemas. 03 Mar 2010 20:58:03 GMT <?xml version="1.0</ns2:amount> <ns2:paid>2010-03-03T21:58:03.1 Content-Type: application/vnd.restbucks.Grab a Receipt • Request HTTP/1.8.restbucks.com"> <link mediaType="application/vnd.

com/order/f932f92d Client Restbucks Service .Poll until the order’s ready • GET from the rel=“order” URI – http://restbucks.

com Connection: keep-alive .1 Host: restbucks.Polling for a ready order on the wire • Request GET /order/1234 HTTP/1.

com/dap"> <ns3:link mediaType="application/vnd.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.restbucks.com/reciept"/> <ns2:item> <ns2:milk>semi</ns2:milk> <ns2:size>large</ns2:size> <ns2:drink>cappuccino</ns2:drink> </ns2:item> <ns2:location>takeaway</ns2:location> <ns2:cost>2.8.Order’s ready.restbucks.com" xmlns:ns3="http://schemas.1 Content-Type: application/vnd.restbucks+xml Content-Length: 534 Date: Wed.com/receipt/1234" rel="http://relations.1 200 OK server: grizzly/1.restbucks+xml" uri="http://restbucks. 03 Mar 2010 20:58:03 GMT <?xml version="1.restbucks. take the receipt and walk away • Response HTTP/1.0</ns2:cost> <ns2:status>ready</ns2:status> </ns2:order> .

Complete the Order • DELETE order at rel=“receipt” URI – http://restbucks.com/receipt/1234 Client Restbucks Service .

Complete the Order • Request DELETE/receipt/1234 HTTP/1.1 Host: restbucks.com Connection: keep-alive .

03 Mar 2010 20:58:03 GMT <?xml version="1.Complete the Order • Response HTTP/1.1 Content-Type: application/xml Content-Length: 393 Date: Wed.restbucks.com/dap"> <ns2:item> <ns2:milk>semi</ns2:milk> <ns2:size>large</ns2:size> <ns2:drink>cappuccino</ns2:drink> </ns2:item> No Hypermedia <ns2:location>takeaway</ns2:location> Controls <ns2:cost>2.com" xmlns:ns3="http://schemas.restbucks.8.0</ns2:cost> <ns2:status>taken</ns2:status> </ns2:order> .0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.1 200 OK server: grizzly/1.

Source: http://images.businessweek.jpg .com/ss/06/07/top_brands/image/starbucks.

What did we learn from Restbucks? • HTTP has a header/status combination for every occasion • APIs are expressed in terms of links. JSON or even default to XHTML as a sensible middle ground • State machines (defined by links) are important – Just as in Web Services… . and links are great! – APP-esque APIs • APIs can also be constructed with URI templates and inference – But beware tight coupling outside of CRUD services! • XML is fine. but we could also use formats like Atom.

References • REST in Practice – Hypermedia and Systems Architecture Jim Webber. Savas Parastatidis. 2010 REST in Practice .A Tutorial on Web-based Services Jim Webber.infoq. Ian Robinson Published by O’Reilly.ly/ctZAhU • • [http://jim.webber. Ian Robinson Presentation for Universities.name] • • .com/articles/rest-introduction REST with Java (JAX-RS) using Jersey – Tutorial: http://bit.A Tutorial on Web-based Services) shared by Jim Webber A Brief Introduction to REST http://www. Savas Parastatidis. shared by Jim Webber Somes slides adapted from a presentation for Universities (REST in Practice .