introduction to rest and jax-rs
DESCRIPTION
An introduction to the architectural style REST and an overview of implementing an application in JAX-RS, the JSR-311 Java REST API.TRANSCRIPT
![Page 1: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/1.jpg)
Java REST in PracticeAsynchronous JAX-RS
Ted Pennings16 December 2010
![Page 2: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/2.jpg)
REST Overview
REST is an architectural style
Client - Server
Most often over HTTP with JSON or XML
Describes the location of resources + actions
![Page 3: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/3.jpg)
REST PrinciplesResource-based
Stateless
Cacheable
Layered, with optional intermediaries
Safety / Idempotency
![Page 4: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/4.jpg)
The Basic Operations
CRUD (Create, Read, Update, Delete)
Performed atomically on one uniquely identified asset or a set of assets
![Page 5: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/5.jpg)
REST with HTTPREST verbs apply directly to HTTP methods
GET - READ
POST - CREATE
PUT - UPDATE
DELETE
Encoded in JSON or XML
Bonus!OPTIONS
HEAD
TRACE
![Page 6: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/6.jpg)
Widget Registry at http://server/widgets
Create a Widget (Bolt, weighs 10g)
REST HTTP Example
POST /widgetsHost: serverUser-agent: Ted’s PresentationContent-type: Application/JSONContent-length: 115
{ widget : { type : ‘bolt’, weight : { amount : 10, unit : ‘grams’ } }}
HTTP/1.1 200 OKDate: Wed, 15 Dec 2010 23:59:59 GMTContent-Type: text/plainTransfer-Encoding: chunked
{ newAssetId: 15 }
Alternatively, could redirect to new asset with Location header
![Page 7: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/7.jpg)
Widget Registry at http://server/widgets
Get Widget from last slide (ID 15 )
Another HTTP Example
GET /widgets/15Host: serverUser-agent: Ted’s Presentation
HTTP/1.1 200 OKDate: Wed, 15 Dec 2010 23:59:59 GMTContent-Type: text/plainTransfer-Encoding: chunkedContent-length: 135
{ widget : { id : 15, type : ‘bolt’, weight : { amount : 10, unit : ‘grams’ } }}
Also available in browser at http://server/widgets/15
![Page 8: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/8.jpg)
Widget Registry at http://server/widgets
Update Widget previously created
Final HTTP Example
HTTP/1.1 200 OKDate: Wed, 15 Dec 2010 23:59:59 GMTContent-Type: text/plainTransfer-Encoding: chunked
PUT /widgets/15Host: serverUser-agent: Ted’s PresentationContent-type: Application/JSONContent-length: 134
{ widget : { id : 15, type : ‘bolt’, weight : { amount : 10, unit : ‘grams’ } }}
(weight was actually 1 gram, typo)
![Page 9: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/9.jpg)
What We Just Saw
REST is resource-oriented
Assets are identified with URLs
The HTTP method specifies the operation
![Page 10: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/10.jpg)
So What?
Putting the important information (what, how) at the HTTP protocol-level allows intermediaries to act and advise
Increased scalability and lower costs
![Page 11: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/11.jpg)
Intermediaries
Two categories:
- Proxies (client-chosen)
- Gateways (provider-chosen)
![Page 12: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/12.jpg)
Client Intermediaries
Mostly proxies
May or may not cache
May alter Javascript for client safety
Firewalls (eg block NSFW + illegal content)
![Page 13: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/13.jpg)
Provider IntermediariesCaching reverse-proxies and CDNs
Message remediation / translation
Security (eg XSRF nonces)
Also, protocol-level load balancing / failover
Should be invisible to client
![Page 14: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/14.jpg)
Safety
Data retrieval methods are considered safe
Should not alter application data
GET / HEAD / OPTIONS / TRACE
Highly Cacheable by intermediaries!
![Page 15: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/15.jpg)
IdempotencyMethods that may be executed more than once with the same result are idempotent
PUT / DELETE
All safe methods are idempotent
POST is not always idempotent
![Page 16: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/16.jpg)
Enter JAX-RS
Abstract specification for tagging resource endpoints and operations in Java code
Annotation-driven
Exposes results of method calls in the same way JAX-WS or Spring-WS does
![Page 17: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/17.jpg)
Using JAX-RSProviders implement it (like JPA)
Provider agnostic ; can easily switch (unlike JPA)
Jersey is the reference implementation
Can couple with message marshallers/unmarshallers
Most rely on JAXB, even for JSON
![Page 18: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/18.jpg)
JAX-RS AnnotationsThe litany found in the javax.ws.rs package...
@Path(“/path”)
@GET / @POST / @PUT / @DELETE /etc
@Produces + @Consumes(“text/plain”)
@PathParam + @HeaderParam + @QueryParam
![Page 19: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/19.jpg)
Creating a Time Service
@Path("/time")public class TimeJaxRsResource {
@GET @Produces("text/plain") public String getCurrentTime() { return new Date().toString(); }
}
http://yourserver/context/time
![Page 20: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/20.jpg)
Using Paths
@Path("/time")public class TimeJaxRsResource { @GET @Path("/eastern") @Produces("text/plain") public String getCurrentEasternTime() { DateFormat format = new SimpleDateFormat(); TimeZone eastern = TimeZone.getTimeZone( "America/New_York"); format.setTimeZone(eastern); return format.format(new Date()); }
}
http://yourserver/context/time/eastern
![Page 21: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/21.jpg)
Using Path Variables
@Path("/time")public class TimeJaxRsResource { @GET @Path("/tz/{timezone}") @Produces("text/plain") public String getTime(@PathParam ("timezone") String tz) { DateFormat format = new SimpleDateFormat(); TimeZone timezone = TimeZone.getTimeZone(tz); format.setTimeZone(timezone); return format.format(new Date()); }
}
http://yourserver/context/time/tz/America_Chicago
![Page 22: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/22.jpg)
What We’ve CreatedStateless
Unfortunately, not useful if cached
Not necessarily asynchronous from a client perspective (due to accuracy concerns)
![Page 23: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/23.jpg)
Message MarshallingJSON to marshall/unmarshall messages
Most commonly used: Jackson
Create a file containing in the following org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider
META-INF/services/javax.ws.rs.ext.MessageBodyReader
META-INF/services/javax.ws.rs.ext.MessageBodyWriter
![Page 24: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/24.jpg)
Example : Prime Numbers
Prime number generation is computationally expensive but fairly simple
Worker thread(s) generate prime numbers
A web UI shows the latest additions http://primes.tedpennings.com/
![Page 25: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/25.jpg)
The Prime Algorithm long x, y; for (x = start; x < Long.MAX_VALUE; x++) { if (x % 2 != 0 || x == 2) { for (y = 2; y <= x / 2; y++) { if (x % y == 0) { break; } } if (y > x / 2) { System.out.println("Discovered prime: " + x); repo.add(x); } } }
![Page 26: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/26.jpg)
The Workers
Stateless loop of code trying to identify primes
Add to MongoDB once found
Simple JAR distributed to workers
Currently, only one; possibility for more
![Page 27: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/27.jpg)
The App
Methods to find the most recent number and batches of numbers greater than X
Exposed over RESTful HTTP with JSON
Runs in Jetty, fronted by an intermediary
http://primes.tedpennings.com/primes/since/13183229
![Page 28: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/28.jpg)
Example Code - Service
@Path("/")public class PrimeJaxRsResource {
private final MongoPrimeRepository repo = new MongoPrimeRepository(); @GET @Path("/since/{since}") @Produces("application/json") public Set<Long> getPrimesSince(@PathParam("since") long since) { LOG.info("Showing the default number of primes since " + since); return repo.getPrimes(since); }
}
http://prime.tedpennings.com/primes/since/1500
![Page 29: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/29.jpg)
The Intermediary
Nginx reverse-proxying Jetty (same node)
Caches all GET operations
![Page 30: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/30.jpg)
The Web UI
Periodical Ajax requests for the numbers since the most recent request (asynchronously)
Does not require full batches
Size varies based on complexity + worker speed
All JavaScript, with jQuery
![Page 31: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/31.jpg)
Demo and Code
Demo and Code Walkthrough
http://primes.tedpennings.com
http://s3.tedpennings.com/prime-jaxrs.zip
![Page 32: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/32.jpg)
Possible Follow-up
Use some kind of MapReduce to distribute workload across multiple workers (Hadoop?)
Use Chef or Puppet to dynamically provision workers and initialize application
![Page 33: Introduction to REST and JAX-RS](https://reader038.vdocuments.us/reader038/viewer/2022103016/554f8404b4c905d25b8b4baa/html5/thumbnails/33.jpg)
Resources (haha)Roy Fielding’s Thesis http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
Jersey site http://jersey.java.net
Wikipedia (surprisingly good for this)
This awesome font : http://www.dafont.com/hand-of-sean.font