Introduction to REST and JAX-RS

34
Java REST in Practice Asynchronous JAX-RS Ted Pennings 16 December 2010

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 of Introduction to REST and JAX-RS

Page 1: Introduction to REST and JAX-RS

Java REST in PracticeAsynchronous JAX-RS

Ted Pennings16 December 2010

Page 2: Introduction to REST and JAX-RS

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

REST PrinciplesResource-based

Stateless

Cacheable

Layered, with optional intermediaries

Safety / Idempotency

Page 4: Introduction to REST and JAX-RS

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

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

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

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

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

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

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

Intermediaries

Two categories:

- Proxies (client-chosen)

- Gateways (provider-chosen)

Page 12: Introduction to REST and JAX-RS

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

The Intermediary

Nginx reverse-proxying Jetty (same node)

Caches all GET operations

Page 30: Introduction to REST and JAX-RS

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

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

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

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