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

Java.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.

IN1163 2011.2011.2</title> <body><h1>Social Machines .2 title title resource http://localhost:8080/IN1163/rest/title HTML representation TEXT representation Social Machines IN1163 .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.2</h1> </body> </html> XML representation http://localhost:8080/IN1163/rest/title Social Machines .2 Multiple resource representations addressed by a single URI .IN1163 2011.IN1163 2011.java <html> <title>Social Machines .xml” • TitleResource.

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

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

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

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 .

.Links as APIs <confirm xmlns="."> <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 ..

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. BPEL Order Drink Add Specialities Order Confirmation Pay Coffee! . roles defined by SOAP – No “operations” – Advertise it with SSDL.

com… – Based on: http://www.com/articles/webber-rest-workflow . 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.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/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.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 .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/1234 h p://restbucks.com/order h p://restbucks.com/order/1234 h ps://restbucks.com/receipt/1234 h p://restbucks.

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

restbucks+xml Host: restbucks.com Connection: keep-alive Content-Length: 283 <?xml version="1.restbucks+xml Accept: application/vnd.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.1 Content-Type: application/vnd.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> .Placing an Order • Request POST /order HTTP/1.restbucks.

restbucks.restbucks+xml" uri="http://restbucks.restbucks.restbucks+xml" uri="http://restbucks.com/update"/> <ns3:link mediaType="application/vnd.1 Location: http://restbucks.restbucks+xml Content-Length: 1039 Date: Wed.com/cancel"/> <ns3:link mediaType="application/vnd.restbucks.com/order/1234 Content-Type: application/vnd.com/order/1234" rel="http://relations.0</ns2:cost> <ns2:status>unpaid</ns2:status> </ns2:order> .0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.com/payment/1234" rel="http://relations.com/payment"/> <ns3:link mediaType="application/vnd.restbucks+xml" uri="http://restbucks.com" xmlns:ns3="http://schemas.restbucks+xml" uri="http://restbucks.Placing an Order • Response HTTP/1.restbucks.com/order/1234" rel="http://relations.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.1 201 Created server: grizzly/1.com/dap"> <ns3:link mediaType="application/vnd.restbucks. 03 Mar 2010 20:58:03 GMT <?xml version="1.8.

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

1 Accept: application/vnd.com Connection: keep-alive .Confirm the Order • Request GET /order/1234 HTTP/1.restbucks+xml Host: 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" uri="http://restbucks.com" xmlns:ns3="http://schemas.restbucks.Confirm the Order • Response HTTP/1.restbucks+xml" uri="http://restbucks.restbucks.restbucks.com/payment/1234" rel="http://relations.com/order/1234" rel="http://relations.com/cancel"/> <ns3:link mediaType="application/vnd.com/payment"/> <ns3:link mediaType="application/vnd.com/order/1234" rel="http://relations.restbucks.restbucks+xml" uri="http://restbucks. 06 Sep 2009 06:51:22 GMT <?xml version="1.0</ns2:cost> <ns2:status>unpaid</ns2:status> </ns2:order> .restbucks.restbucks+xml" uri="http://restbucks.com/order/1234 Content-Type: application/vnd.com/dap"> <ns3:link mediaType="application/vnd.restbucks+xml Content-Length: 911 Date: Sun.1 200 OK Location: http://restbucks.com/update"/> <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 .

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> .0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.1 Content-Type: application/vnd.com Connection: keep-alive Content-Length: 288 <?xml version="1.restbucks+xml Accept: application/vnd.restbucks.restbucks+xml Host: restbucks.Change the Order • Request POST order/1234 HTTP/1.

com/order/1234 Content-Type: application/vnd.com/dap"> <ns3:link mediaType="application/vnd.restbucks+xml" uri="http://restbucks.restbucks+xml" uri="http://restbucks.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.restbucks+xml" uri="http://restbucks.restbucks.com/order/1234" rel="http://relations.com/payment"/> <ns3:link mediaType="application/vnd.restbucks.com/cancel"/> <ns3:link mediaType="application/vnd.com/update"/> <ns3:link mediaType="application/vnd.com/order/1234" rel="http://relations.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" xmlns:ns3="http://schemas.restbucks.1 200 OK Location: http://restbucks.com/payment/1234" rel="http://relations. 06 Sep 2009 06:52:22 GMT <?xml version="1.restbucks+xml Content-Length: 916 Date: Sun.restbucks.0</ns2:cost> <ns2:status>unpaid</ns2:status> </ns2:order> .restbucks+xml" uri="http://restbucks.Change the Order • Response HTTP/1.

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 .

.com  Response Allow: GET Too slow! Someone else has changed the state of my order ..1 Host: restbucks.  Response 409 Conflict  Request OPTIONS /order/1234 HTTP 1.com .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.

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

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

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

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

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

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

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

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

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

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

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

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

restbucks. take the receipt and walk away • Response HTTP/1.restbucks+xml" uri="http://restbucks.com/dap"> <ns3:link mediaType="application/vnd.restbucks.Order’s ready.restbucks+xml Content-Length: 534 Date: Wed.0</ns2:cost> <ns2:status>ready</ns2:status> </ns2:order> .restbucks.1 Content-Type: application/vnd.1 200 OK server: grizzly/1.com/receipt/1234" rel="http://relations.8. 03 Mar 2010 20:58:03 GMT <?xml version="1.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.com" xmlns:ns3="http://schemas.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.

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

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

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.Complete the Order • Response HTTP/1.0</ns2:cost> <ns2:status>taken</ns2:status> </ns2:order> .restbucks. 03 Mar 2010 20:58:03 GMT <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:order xmlns:ns2="http://schemas.1 Content-Type: application/xml Content-Length: 393 Date: Wed.1 200 OK server: grizzly/1.8.com" xmlns:ns3="http://schemas.restbucks.

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

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.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… .

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