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.

Speakers


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.