Presentation JAX-RS 2.0: RESTful Java on Steroids
JAX-RS 1.X has been a hugely successful Java API for RESTful services development and a lot of real-world experience has resulted in a number of new features being proposed. JSR 339 was created in early 2011 with the objective of exploring and scoping all these proposals. The purpose of this talk is to elaborate on all the new planned features.
The most commonly requested feature for JAX-RS 2.0 is a client API. Client APIs can range from low-level, just above HttpURLConnection, to high-level, often including support for IoC and hyperlinking. Other features that will be covered in this presentation include: asynchronous processing, hypermedia, validation, interceptors, improved content negotiation, as well as better integration with other specifications such as JSR 330.
Published on: 2011-12-20T07:33:50.000Z
Channel: Devoxx'11 (all)
Tags: Java rest
Speakers:
Marek Potociar
Marek Potociar is a Principal Software Engineer at Oracle. He's been involved with web services development for the last eight years. At present, Marek is a specification lead of Java EE RESTful web services API (JAX-RS) as well as the development lead of the next major JAX-RS reference implementation release. Previous to this role Marek was leading development on Metro - The open-source SOAP web services framework for Java.
PDF: slides.pdf
Slides:
JAX-RS 2.0: RESTful Java on Steroids
JAX-RS 2.0: RESTful Java on Steroids
What's in JSR-339?
Marek Potociar JAX-RS 2.0 Specification Lead Oracle
The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be rel
The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle s products remains at the sole discretion of Oracle.
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Part I.
Part I.
How we got here...
Shortest REST Primer Ever
Shortest REST Primer Ever
· RESTFul Principles
Assign everything an ID Link things together Use common set of methods Allow multiple representations Stateless communications
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
JAX-RS Intro
JAX-RS Intro
· JAX-RS 1.0 is Java API for RESTful Services
Current version: JAX-RS 1.1
· Goals
POJO-Based Resource API
· Server-side
HTTP Centric Entity Format Independence Container Independence Inclusion in Java EE
· But no hard dependency on Java EE though
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
JAX-RS API
JAX-RS API
@Path("atm/{cardId}") public class AtmResource { @GET @Path("balance") @Produces("text/plain") public String balance(@PathParam("cardId") String card, @QueryParam("pin") String pin) { return Double.toString(getBalance(card, pin)); } ...
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
JAX-RS API
JAX-RS API
@Path("atm/{cardId}") public class AtmResource { @GET @Path("balance") @Produces("text/plain") public String balance(@PathParam("cardId") String card, @QueryParam("pin") String pin) { return Double.toString(getBalance(card, pin)); } ... Resource path templates
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
JAX-RS API
JAX-RS API
@Path("atm/{cardId}") public class AtmResource { @GET @Path("balance") @Produces("text/plain") public String balance(@PathParam("cardId") String card, @QueryParam("pin") String pin) { return Double.toString(getBalance(card, pin)); } ... URI parameter injection Resource path templates
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
JAX-RS API
JAX-RS API
@Path("atm/{cardId}") public class AtmResource { @GET @Path("balance") @Produces("text/plain") public String balance(@PathParam("cardId") String card, @QueryParam("pin") String pin) { return Double.toString(getBalance(card, pin)); } ... HTTP method binding
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Resource path templates URI parameter injection
JAX-RS API
JAX-RS API
@Path("atm/{cardId}") public class AtmResource { @GET @Path("balance") @Produces("text/plain") public String balance(@PathParam("cardId") String card, @QueryParam("pin") String pin) { return Double.toString(getBalance(card, pin)); } ... HTTP method binding Built-in Serialization
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Resource path templates URI parameter injection
JAX-RS API
JAX-RS API
... @POST @Path("withdrawal") @Consumes("text/plain") @Produces("application/json") public Money withdraw(@PathParam("card") String card, @QueryParam("pin") String pin, String amount){ return getMoney(card, pin, amount); } }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
JAX-RS API
JAX-RS API
... @POST @Path("withdrawal") @Consumes("text/plain") @Produces("application/json") public Money withdraw(@PathParam("card") String card, @QueryParam("pin") String pin, String amount){ return getMoney(card, pin, amount); } } Custom Serialization
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Built-in Serialization
JAX-RS Most Wanted
JAX-RS Most Wanted
Validation Filters Handlers Client API MVC Hypermedia Asynchronous Processing
JSR 330
Server Side Conneg
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
JSR 339: JAX-RS 2.0
JSR 339: JAX-RS 2.0
· EG Formed in February 2011
Oracle Leads
· Marek Potociar / Santiago Pericas-Geertsen
Expert Group:
· Jan Algermissen, Florent Benoit (OW2), Sergey Beryozkin (Talend), Adam Bien, Bill Burke (RedHat), Clinton Combs, Bill De Hora, Markus Karg, Sastri Malladi (Ebay), Julian Reschke, Guilherme Silveira, Dionysios Synodinos
· Early Draft published on Oct 21st, 2011
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Part II.
Part II.
Where we are going...
New in JAX-RS 2.0
New in JAX-RS 2.0
Validation
Filters Handlers
Client API
Asynchronous Processing
MVC
JSR 330
Hypermedia
Server Side Conneg
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client API
Client API
Validation Filters Handlers Client API Hypermedia Asynchronous Processing
JSR 330
Server Side Conneg
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client API
Client API
· HTTP client libraries too low level · Sharing features with JAX-RS server API
E.g., MBRs and MBWs
· Supported by some JAX-RS 1.x implementations
Need for a standard
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client API
Client API
Client Factory Client Resource Target "atm"
Configuration Configuration Configuration
Resource Target "{cardId}"
Invocation
Request Builder
Resource Target "balance"
Resource Target "withdrawal"
Response
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client API
Client API
// Get instance of Client Client client = ClientFactory.newClient();
// Get account balance String bal = client.target("http://.../atm/{cardId}/balance") .pathParam("cardId", "111122223333") .queryParam("pin", "9876") .request("text/plain").get(String.class);
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client API
Client API
// Withdraw some money Money mon = client.target("http://.../atm/{cardId}/withdrawal") .pathParam("cardId", "111122223333") .queryParam("pin", "9876") .request("application/json") .post(text("50.0"), Money.class);
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client API
Client API
Invocation inv1 = client.target("http://.../atm/{cardId}/balance")... .request("text/plain").buildGet();
Invocation inv2 = client.target("http://.../atm/{cardId}/withdraw")... .request("application/json") .buildPost(text("50.0"));
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client API
Client API
Collection invocations = Arrays.asList(inv1, inv2); Collection responses = Collections.transform( invocations, new F() { public Response apply(Invocation inv) { return inv.invoke(); } });
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Client API
Client API
// Create client and register MyProvider1 Client client = ClientFactory.newClient(); client.configuration().register(MyProvider1.class); // Create atm target; inherits MyProvider1 Target atm = client.target("http://.../atm"); // Register MyProvider2 atm.configuration().register(MyProvider2.class); // Create balance target; inherits MyProvider1, MyProvider2 Target balance = atm.path("{cardId}/balance"); // Register MyProvider3 balance.configuration().register(MyProvider3.class);
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers
Filters & Handlers
Validation Filters Handlers Client API Hypermedia Asynchronous Processing
JSR 330
Server Side Conneg
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers
Filters & Handlers
· Customize JAX-RS request/response processing
Use Cases: Logging, Compression, Security, Etc.
· Shared by client and server APIs · Replace existing proprietary support
Provided by most JAX-RS 1.x implementations
· All using slightly different types or semantics
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers
Filters & Handlers
· Non-wrapping filter chain
Managed by the JAX-RS runtime Each filter decides to proceed or break the chain
· By returning FilterAction.NEXT or FilterAction.STOP
· Request Request
RequestFilter interface
· Server-side specialty: PreMatchRequestFilter
· Response Response
ResponseFilter interface
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers
Filters & Handlers
@Provider class LoggingFilter implements RequestFilter, ResponseFilter { // RequestFilter implementation @Override public FilterAction preFilter(FilterContext ctx) throws IOException { logRequest(ctx.getRequest()); return FilterAction.NEXT; } ...
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers
Filters & Handlers
... // ResponseFilter implementation @Override public FilterAction postFilter(FilterContext ctx) throws IOException { logResponse(ctx.getResponse()); return FilterAction.NEXT; } }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers
Filters & Handlers
· Wrapping handler (interceptor) chain
Each handler decides to proceed or break chain
· By calling context.proceed()
· Read message handler
ReadFromHandler interface
· Write message handler
WriteToHandler interface
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers
Filters & Handlers
@Provider class GzipHandler implements ReadFromHandler { @Override public Object readFrom(ReadFromHandlerContext context) throws IOException { if (gzipEncoded(context)) { InputStream old = context.getInputStream(); context.setInputStream(new GZIPInputStream(old)); } return context.proceed(); } }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers Bindings
Filters & Handlers Bindings
· Associating filters and handlers with resources · Declaring relative position in the chain
@BindingPriority(priority)
· Same mechanism for filters and handlers
Name Binding Static Dynamic @NameBinding / @Qualifier ? DynamicBinding interface Global Binding DEFAULT DynamicBinding interface
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers Bindings
Filters & Handlers Bindings
@NameBinding // or @Qualifier ? @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface Logged { } @Provider @Logged @BindingPriority(USER) public class LoggingFilter implements RequestFilter, ResponseFilter { ... }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Filters & Handlers Bindings
Filters & Handlers Bindings
@Path("/greet/{name}") @Produces("text/plain") public class MyResourceClass { @Logged @GET public String hello(@PathParam("name") String name) { return "Hello " + name; } }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Validation
Validation
Validation Filters Handlers Client API Hypermedia Asynchronous Processing
JSR 330
Server Side Conneg
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Validation
Validation
· Services must validate data · Bean Validation already provides the mechanism
Integration into JAX-RS
· Support for constraint annotations in:
Fields and properties Parameters (including request entity) Methods (response entities) Resource classes
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Validation
Validation
@Path("/") class MyResourceClass { @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public void registerUser( Built-in @NotNull @FormParam("firstName") String firstName, @NotNull @FormParam("lastName") String lastName, @Email @FormParam("email") String email) { ... } } Custom
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Validation
Validation
@Target({ METHOD, FIELD, PARAMETER }) @Retention(RUNTIME) @Constraint(validatedBy = EmailValidator.class) public @interface Email { ... } class EmailValidator implements ConstraintValidator { public void initialize(Email email) { ... } public boolean isValid(String value, ConstraintValidatorContext context) { // Check 'value' is e-mail address ... } }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Validation
Validation
@ValidationA class User { ... } @Path("/") class MyResourceClass { @POST @Consumes("application/xml") public void registerUser1(@Valid User u) { ... } @POST @Consumes("application/json") public void registerUser12(@ValidationB @Valid User u) { ... } }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Async Processing
Async Processing
Validation Filters Handlers Client API Hypermedia Asynchronous Processing
JSR 330
Server Side Conneg
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Async Processing
Async Processing
· Server API support
Off-load container threads
· Long-running operations
Efficient asynchronous event processing
· Suspend while waiting for an event · Resume when event arrives
Leverage Servlet 3.x async support (if available)
· Client API support
Asynchronous request invocation API
· Future, InvocationCallback
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Async Processing
Async Processing
@Path("/async/longRunning") public class MyResource { @Context private ExecutionContext ctx; @GET @Produces("text/plain") @Suspend public void longRunningOp() { Executors.newSingleThreadExecutor().submit( new Runnable() { public void run() { ... ctx.resume("Hello async world!"); } }); } }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Async Processing
Async Processing
@Path("/async/longRunning") public class MyResource { @Context private ExecutionContext ctx; @GET @Produces("text/plain") public void longRunningOp() { Executors.newSingleThreadExecutor().submit( new Runnable() { public void run() { ... ctx.resume("Hello async world!"); } }); ctx.suspend(); } }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
// Suspend connection and return
Async Processing
Async Processing
// Build target URI Target target = client.target("http://.../balance")... // Start async call and register callback Future> handle = target.request().async().get( new InvocationCallback() { public void complete(String balance) { ... } public void failed(InvocationException e) { ... } }); // After waiting for a while ... if (!handle.isDone()) handle.cancel(true);
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Hypermedia
Hypermedia
Validation Filters Handlers Client API Hypermedia Asynchronous Processing
JSR 330
Server Side Conneg
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Hypermedia
Hypermedia
· REST principles
Identifiers and Links HATEOAS (Hypermedia As The Engine Of App State)
· Link types:
Structural Links Transitional Links
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Hypermedia
Hypermedia
Link: ; rel=ship, ; rel=cancel ... http://.../customers/11 http://.../customers/11/address/1 - http://.../products/111 2
...
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Transitional Links
Structural Links
Hypermedia
Hypermedia
· Transitional Links Only · Link and LinkBuilder classes
RFC 5988: Web Linking
· Support for Link in ResponseBuilder · Create Target from Link in Client API
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Hypermedia
Hypermedia
// Producer API (server-side) Link self = Link.fromResourceMethod(MyResource.class, "handleGet") .build(); Link update = Link .fromResourceMethod(MyResource.class, "handlePost") .rel("update").build(); ... Response res = Response.ok(order) .link("http://.../orders/1/ship", "ship") .links(self, update) .build();
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Hypermedia
Hypermedia
Response order = client.target(...).request("application/xml").get(); // Consumer API (client-side) if (order.getLink("ship") != null) { Response shippedOrder = client.target(order.getLink("ship")) .request("application/xml").post(...); ... }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Other Topics
Other Topics
Validation Filters Handlers Client API ... Hypermedia Asynchronous Processing
JSR 330
Server Side Conneg
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Server Side Conneg
Server Side Conneg
GET http://.../widgets2 Accept: text/*; q=1 ...
Path("widgets2") public class WidgetsResource2 { @GET @Produces("text/plain", "text/html") public Widgets getWidget() {...} }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Server Side Conneg
Server Side Conneg
GET http://.../widgets2 Accept: text/*; q=1 ...
Path("widgets2") public class WidgetsResource2 { @GET @Produces("text/plain; qs=0.5", "text/html; qs=0.75") public Widgets getWidget() {...} }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Other Topics
Other Topics
· Better integration with JSR 330
Support @Inject and @Qualifier @Qualifier as a replacement for @NamedBinding ? Provider vs. ContextResolver
· Support for MVC ? · High-level client API ?
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Thank You!
Thank You!
http://jcp.org/en/jsr/detail?id=339 (JSR) http://java.net/projects/jax-rs-spec (Project) users@jax-rs-spec.java.net (Users alias)
Filters & Handlers Bindings
Filters & Handlers Bindings
@NameBinding // or @Qualifier ? @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface Logged { } @Provider @Logged @BindingPriority(USER) public class LoggingFilter implements RequestFilter, ResponseFilter { ... }
Copyright
©
2011,
Oracle
and/or
its
affiliates.
All
rights
reserved.