JAX-RS 2.0: New and
Noteworthy in RESTful
Web Services API
Arun Gupta
Java EE & GlassFish Guy
blogs.oracle.com/arungupta, @arungupta



1   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS - Java API for RESTful Services



        Standard annotation-driven API                                     §  POJO-Based Resource Classes

          that aims to help developers                                     §  HTTP Centric Programming Model
    build RESTful Web services and clients                                 §  Entity Format Independence
                     in Java                                               §  Container Independence
                                                                           §  Included in Java EE




2   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Example: JAX-RS APIResources
    @Path("/atm/{cardId}")	                                    URI Parameter
    public class AtmService {	                                   Injection
    	
        @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                                                             Built-in
       Binding                                                             Serialization



3   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Example: JAX-RS API (contd.)
                       …	                                                  Custom Serialization
      	
                   @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);	
                   }	
      }	




4   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Example: JAX-RS API (contd.)




5   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Example: JAX-RS API (contd.)




6   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JSR-339 a.k.a. JAX-RS 2.0

§  Expert Group formed in February, 2011
         –  Lead by Oracle
             §  Marek Potociar, Santiago Pericas-Geertsen
         –  13 Group members
             §  Jan Algermissen, Florent Benoit (OW2), Sergey Beryozkin (Talend/CXF), Adam Bien,
                 Bill Burke (RedHat), Clinton L Combs, Bill De Hora, Markus Karg, Sastry Mallady
                 (eBay), Wendy Raschke (IBM), Julian Reschke, Guilherme Silveira, Dionysios
                 Synodinos

§  Public Review Draft published on Sep 28, 2012
         –  See JSR-339 JCP site jcp.org/en/jsr/detail?id=339




7   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0

    §  Client API
    §  Common configuration
    §  Asynchronous processing
    §  Filters
    §  Interceptors
    §  Hypermedia support
    §  Server-side content negotiation

8   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0

    §  Client API
    §  Common configuration
    §  Asynchronous processing
    §  Filters
    §  Interceptors
    §  Hypermedia support
    §  Server-side content negotiation

9   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Client API
Motivation


 §  HTTP client libraries too low level
 §  Leveraging providers and concepts from the JAX-RS 1.x API
          –  E.g., MBRs and MBWs
 §  Proprietary APIs introduced by major JAX-RS 1.x implementations
          –  Need for a standard




10   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Client API


 // Get instance of Client
 Client client = ClientFactory.newClient();


 // Get account balance
 String bal = client.target("http://.../atm/{cardId}/balance")
     .resolveTemplate("cardId", "111122223333")
     .queryParam("pin", "9876")
     .request("text/plain").get(String.class);


11   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Client API


 // Withdraw some money
 Money mon = client.target("http://.../atm/{cardId}/withdrawal")
     .resolveTemplate("cardId", "111122223333")
     .queryParam("pin", "9876")
     .request("application/json")
     .post(text("50.0"), Money.class);




12   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
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"));


13   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Client API

 Collection<Invocation> invocations = Arrays.asList(inv1, inv2);

 Collection<Response> responses = Collections.transform(
         invocations,
         new F<Invocation, Response>() {
             public Response apply(Invocation inv) {
                 return inv.invoke();
             }
         });




14   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Client API

 // Create client and register MyProvider1
 Client client = ClientFactory.newClient();
 client.configuration().register(MyProvider1.class);

 // Create atm target; inherits MyProvider1
 WebTarget atm = client.target("http://.../atm");
 // Register MyProvider2
 atm.configuration().register(MyProvider2.class);

 // Create balance target; inherits MyProvider1, MyProvider2
 WebTarget balance = atm.path(”{cardId}/balance");
 // Register MyProvider3
 balance.configuration().register(MyProvider3.class);

15   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0

     §  Client API
     §  Common configuration
     §  Asynchronous processing
     §  Filters
     §  Interceptors
     §  Hypermedia support
     §  Server-side content negotiation

16   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Common configuration - motivation
Client-side


 client.configuration()
         .register(JsonMessageBodyReader.class)
         .register(JsonMessageBodyWriter.class)
         .register(JsonpInterceptor.class)
         .setProperty(“jsonp.callback.name”, “callback”)
         .setProperty(“jsonp.callback.queryParam”, “true”)
         ...




17   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Common configuration - motivation
Server-side
 public class MyApp extends javax.ws.rs.core.Application {
     public Set<Class<?>> getClasses() {
         Set<Class<?>> classes = new HashSet<…>();
         …
         classes.add(JsonMessageBodyReader.class);
         classes.add(JsonMessageBodyWriter.class);
         classes.add(JsonpInterceptor.class);
         …
         return classes;
     }
 }



18   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Common configuration - solution
Client-side
 client.configuration()
         .register(JsonMessageBodyReader.class)
         .register(JsonMessageBodyWriter.class)
         .register(JsonpInterceptor.class)
         .setProperty(“jsonp.callback.name”, “callback”)
         .setProperty(“jsonp.callback.queryParam”, “true”)
         ...



 JsonFeature jf = new JsonFeature().enableCallbackQueryParam();
 Client.configuration().register(jf);


19   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Common configuration - solution
Server-side
 public Set<Class<?>> getClasses() {
     …
     classes.add(JsonMessageBodyReader.class);
     classes.add(JsonMessageBodyWriter.class);
     classes.add(JsonpInterceptor.class);
     …
 }

 public Set<Class<?>> getClasses() {
     …
     classes.add(JsonFeature.class);
     …
 }

20   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Common configuration

 public interface Configurable {
     Map<String, Object> getProperties();
     Object getProperty(String name);
                Configurable setProperties(Map<String, ?> properties);
                Configurable setProperty(String name, Object value);
                Collection<Feature> getFeatures();
                Set<Class<?>> getProviderClasses();
                Set<Object> getProviderInstances();
                Configurable register(...);
                ...
 }


21   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Common configuration



 public interface Feature {
     boolean configure(Configurable configurable);
 }




22   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
A Feature example

 public void JsonFeature implements Feature {

               public boolean configure(Configurable config) {
                   config.register(JsonMessageBodyReader.class)
                         .register(JsonMessageBodyWriter.class)
                         .register(JsonpInterceptor.class)
                         .setProperty(CALLBACK_NAME, calbackName)
                         .setProperty(USE_QUERY_PARAM, useQueryParam);

                              return true;
               }
 }


23   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Dynamic Feature
Server-side only
 public interface DynamicFeature {
     void configure(ResourceInfo ri, Configurable configurable);
 }

 public interface ResourceInfo {
     Method getResourceMethod();
     Class<?> getResourceClass();
 }




24   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0

     §  Client API
     §  Common configuration
     §  Asynchronous processing
     §  Filters
     §  Interceptors
     §  Hypermedia support
     §  Server-side content negotiation

25   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Async Processing

 §  Server API support
      –  Off-load I/O 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<RESPONSE>, InvocationCallback<RESPONSE>	
  



26   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Async Processing: Server-side

 @Path("/async/longRunning")
 public class MyResource {
             @GET
             public void longRunningOp(@Suspended AsyncResponse ar) {
                          ar.setTimeoutHandler(new MyTimoutHandler());
                          ar.setTimeout(15, SECONDS);
                          Executors.newSingleThreadExecutor().submit(new Runnable() {
                              public void run() {
                                  …
                                  ar.resume(result);
                              }
                          });
             }
 }



27   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Async Processing: Server-side
 public interface AsyncResponse {
     public void resume(Object/Throwable response);
            public void cancel();
            public void cancel(int/Date retryAfter);
            public boolean isSuspended();
            public boolean isCancelled();
            public boolean isDone();
            public void setTimeout(long time, TimeUnit unit);
            public void setTimeoutHandler(TimeoutHandler handler);
            public                boolean register(Class<?> callback);
            public                boolean[] register(Class<?> callback, Class<?>... callbacks);
            public                boolean register(Object callback);
            public                boolean[] register(Object callback, Object... callbacks);
 }



28   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Async Processing: Server-side

 @Target({ElementType.PARAMETER})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface Suspended {
 }


 public interface TimeoutHandler {
     void handleTimeout(AsyncResponse asyncResponse);
 }


29   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Async Processing: Server-side

 public interface ResumeCallback {
     public void onResume(AsyncResponse resuming, Response response);
     public void onResume(AsyncResponse resuming, Throwable error);
 }

 public interface CompletionCallback {
     public void onComplete();
     public void onError(Throwable throwable);
 }

 public interface ConnectionCallback {
     public void onDisconnect(AsyncResponse disconnected);
 }


30   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Async Processing: Client-side

 WebTarget target = client.target("http://.../balance”)…

 // Start async call and register callback
 Future<?> handle = target.request().async().get(
     new InvocationCallback<String>() {
         void complete(String balance) { … }
         void failed(InvocationException e) { … }
     });

 // After waiting for too long…
 if (!handle.isDone()) handle.cancel(true);



31   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0

     §  Client API
     §  Common configuration
     §  Asynchronous processing
     §  Filters
     §  Interceptors
     §  Hypermedia support
     §  Server-side content negotiation

32   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Filters & Interceptors
Motivation


 §  Customize JAX-RS request/response processing
          –  Use Cases: Logging, Compression, Security, Etc.
 §  Introduced for client and server APIs
 §  Replace existing proprietary support
          –  Provided by most JAX-RS 1.x implementations
                       §  All using slightly different types or semantics




33   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Filters & Interceptors
Filter each incoming/outgoing message
                                                                            §  Request è Request
                                                                               –  ContainerRequestFilter,	
  
 §  Non-wrapping filter chain
                                                                                 ClientRequestFilter	
  
          –  Filters do not invoke next filter in
                 the chain directly
                                                                            §  Response è Response
          –  managed by the JAX-RS runtime
                                                                               –  ContainerResponseFilter,	
  
                                                                                 ClientResponseFilter
 §  Each filter decides to proceed or
     break the chain                                                        §  Server-side specialties
                                                                               –  @PreMatching,	
  DynamicFeature


34   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Filters & Interceptors
A Logging Filter Example

public class RequestLoggingFilter implements ContainerRequestFilter {

            @Override
            public void filter(ContainerRequestContext requestContext) {

                           log(requestContext);

                           // non-wrapping => returns without invoking the next filter
            }

            ...
}


35   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Filters & Interceptors
Intercept entity providers
 §  Invoked ONLY when/if entity                                            §  MessageBodyReader interceptor
     processing occurs                                                        –  ReaderInterceptor interface
          –  Performance boost

                                                                            §  MessageBodyWriter interceptor
 §  Wrapping interceptor chain                                               –  WriterInterceptor interface
          –  Each interceptor invokes the next
                 one in the chain via
                 context.proceed()	
  



36   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Filters & Interceptors
A GZip Reader Interceptor Example

     public class GzipInterceptor implements ReaderInterceptor {
         @Override
         Object aroundReadFrom(ReaderInterceptorContext ctx) {
             InputStream old = ctx.getInputStream();
             ctx.setInputStream(new GZIPInputStream(old));

                                    // wrapping => invokes the next interceptor
                                    Object entity = ctx.proceed();

                                    ctx.setInputStream(old);
                                    return entity;
                    }
     }


37   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Filters & Interceptors
                                                                            write(…)

                                                                                    Writer
                                                                                 Interceptor
                                                                                               …        Writer
                                                                                                     Interceptor
                                                                                                                         MBW




                                                     Request                  Filter      …        Filter
                Application                                                                                        Transport   Network
                                                     Response                 Filter      …        Filter




                                               read(…) - optional

                                                          MBR
                                                                              Reader
                                                                            Interceptor
                                                                                          …      Reader
                                                                                               Interceptor




38   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Filters & Interceptors                                                                                      read(…) - optional

                                                                                                                  Reader
                                                                                                                Interceptor
                                                                                                                               …          Reader
                                                                                                                                        Interceptor
                                                                                                                                                       MBR

                                                                            @PreMatching



                                         Request                            Filter        Filter
                                                                                                       Resource
                                                                                                       Matching
                                                                                                                          Filter    …         Filter    Request
 Network                                                                                                                                                     Application

                                     Response                                Filter                …             Filter        Filter         Filter   Response



                            write(…)

                                      MBW
                                                                     Writer
                                                                  Interceptor
                                                                                      …          Writer
                                                                                              Interceptor




39   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Bindings & Priorities
             §  Binding
                       –  Associating filters and interceptors with resource methods
                       –  Server-side concept
             §  Priority
                       –  Declaring relative position in the execution chain
                       –  @BindingPriority(int	
  priority)	
  
             §  Shared concept by filters and interceptors



                                                                            Scoped Binding   Global Binding

                                                                                                 Default
                Static                                      @NameBinding (@Qualifier?)
                                                                                             @PreMatching


           Dynamic                                                          DynamicFeature        N/A

40   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Bindings

@NameBinding // or @Qualifier ?
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Logged {}

@Provider
@Logged
@BindingPriority(USER)
public class LoggingFilter
    implements ContainerRequestFilter, ContainerResponseFilter { … }




41   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Bindings


@Path("/greet/{name}")
@Produces("text/plain")
public class MyResourceClass {

               @Logged
               @GET
               public String hello(@PathParam("name") String name) {
                    return "Hello " + name;
               }
}

42   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
A DynamicFeature example
Server-side only
 public void SecurityFeature implements DynamicFeature {

               public boolean configure(ResourceInfo ri, Configurable config) {
                   String[] roles = getRolesAllowed(ri);

                              if (roles != null) {
                                  config.register(new RolesAllowedFilter(roles));
                              }
               }
               …
 }



43   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0

     §  Client API
     §  Common configuration
     §  Asynchronous processing
     §  Filters
     §  Interceptors
     §  Hypermedia support
     §  Server-side content negotiation

44   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Hypermedia

 §  REST principles
          –  Identifiers and Links
          –  HATEOAS (Hypermedia As The Engine Of App State)


 §  Link types:
          –  Structural Links
          –  Transitional Links




45   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Hypermedia
                                                                            Transitional Links
Link: <http://.../orders/1/ship>; rel=ship,
      <http://.../orders/1/cancel>; rel=cancel
      ...
<order id="1">
    <customer>http://.../customers/11</customer>
    <address>http://.../customers/11/address/1</address>
    <items>
         <item>                                          Structural Links
             <product>http://.../products/111</product>
             <quantity>2</quantity>
         </item>
    <items>
    ...
</order>


46   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Hypermedia

 §  Link and LinkBuilder classes
          –  RFC 5988: Web Linking
 §  Support for Link in ResponseBuilder and filters	
  
          –  Transitional links (headers)
 §  Support for manual structural links
          –  Via Link.JaxbAdapter & Link.JaxbLink
 §  Create a resource target from a Link in Client API




47   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
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();


48   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Hypermedia

 Response order = client.target(…).request("application/xml").get();

 // Consumer API (client-side)
 Link shipmentLink = order.getLink(“ship”);
 if (shipmentLink != null) {
     Response shipment = client.target(shipmentLink).post(null);
     …
 }




49   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0

     §  Client API
     §  Common configuration
     §  Asynchronous processing
     §  Filters
     §  Interceptors
     §  Hypermedia support
     §  Server-side content negotiation

50   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Server Side Conneg

 GET http://.../widgets2
 Accept: text/*; q=1
 …


 Path("widgets2")
 public class WidgetsResource2 {
     @GET
     @Produces("text/plain", "text/html")
     public Widgets getWidget() {...}
 }

51   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
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() {...}
 }

52   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0 Summary

 §  Major new features
          –  Client API, Filters & Interceptors, Asynchronous Resources, Hypermedia


 §  Many minor API improvements and extensions
          –  Request / Response, URI builder, String Converters, @BeanParam,
                 MultivaluedHashMap, GenericType, …

 §  Improved TCK coverage = improved portability
          –  ~350 tests in JAX-RS 1.x, ~1700 tests in JAX-RS 2.0



53   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
<a href=“…” >JAX-RS 2.0</a>

 §  Project web site                                                       jax-rs-spec.java.net
 §  Users mailing list                                                     users@jax-rs-spec.java.net
 §  JSR-339 site                                                           jcp.org/en/jsr/detail?id=339

          –  Latest specification text draft
                       §  java.net/projects/jax-rs-spec/sources/git/content/spec/spec.pdf
          –  Latest API snapshot
                       §  jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/index.html



54   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
<a href=“…” >Jersey 2.0</a>

 §  Project web site                                                       jersey.java.net
 §  Users mailing list                                                     users@jersey.java.net

          –  Latest users guide
                       §  http://jersey.java.net/nonav/documentation/snapshot/index.html
          –  Latest API documentation
                       §  http://jersey.java.net/nonav/apidocs/snapshot/jersey/index.html




55   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
56   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
57   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0

      §  DI (JSR-330) Integration
      §  Bean Validation
      §  Improved Java EE Security Support
      §  Presentation Layer
      §  High-level Client API




58   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Dependency Injection Integration

 §  Support Java Dependency Injection API (JSR-330)
      –  Support	
  @Inject	
  and	
  @Qualifier ?
      –  @Qualifier	
  as a replacement for	
  @NamedBinding	
  ?
      –  Provider vs.	
  ContextResolver ?
      –  Support DI (JSR-330) or CDI (JSR-299)?


 §  Issues
       –  Interference with CDI providers
       –  EG does not see enough added value for DI


 §  DI-style injection support deferred




59   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Dependency Injection Integration
Support DI (JSR-330) or CDI (JSR-299)?
 §  Java EE Deployments
          –  Tight CDI integration makes sense (unification of Java EE component
                 model)
 §  Java SE Deployments
          –  DI provides all the required features
          –  CDI is too heavy-weight
                       §  Many redundant features
                                   –  method interceptors, decorators, stereotypes …
                       §  Additional limitations put on managed components



60   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Bean Validation

 §  Dropped from JAX-RS 2.0 Public Review
          –  Difficulty aligning schedules
 §  Still supported via CDI 1.1
          –  JAX-RS resource class must be CDI bean
          –  BV 1.1 now supports method validation
 §  May revisit current plan post Java EE 7




61   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
More Topics…

 §  Improved Java EE security                                              §  High-level client API
     support                                                                   –  Hard to design it to be RESTful
          –  @RolesAllowed, …
                                                                               –  Jersey 2 provides an
          –  SecurityContext.authenticate(…)
                                                                                  experimental support
                                                                               –  Don’t want to end-up with an
 §  Pluggable Views                                                              RPC-style API
          –  Completes the MVC pattern




62   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.

JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London

  • 1.
    JAX-RS 2.0: Newand Noteworthy in RESTful Web Services API Arun Gupta Java EE & GlassFish Guy blogs.oracle.com/arungupta, @arungupta 1 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 2.
    JAX-RS - JavaAPI for RESTful Services Standard annotation-driven API §  POJO-Based Resource Classes that aims to help developers §  HTTP Centric Programming Model build RESTful Web services and clients §  Entity Format Independence in Java §  Container Independence §  Included in Java EE 2 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 3.
    Example: JAX-RS APIResources @Path("/atm/{cardId}") URI Parameter public class AtmService { Injection @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 Built-in Binding Serialization 3 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 4.
    Example: JAX-RS API(contd.) … Custom Serialization @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); } } 4 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 5.
    Example: JAX-RS API(contd.) 5 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 6.
    Example: JAX-RS API(contd.) 6 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 7.
    JSR-339 a.k.a. JAX-RS2.0 §  Expert Group formed in February, 2011 –  Lead by Oracle §  Marek Potociar, Santiago Pericas-Geertsen –  13 Group members §  Jan Algermissen, Florent Benoit (OW2), Sergey Beryozkin (Talend/CXF), Adam Bien, Bill Burke (RedHat), Clinton L Combs, Bill De Hora, Markus Karg, Sastry Mallady (eBay), Wendy Raschke (IBM), Julian Reschke, Guilherme Silveira, Dionysios Synodinos §  Public Review Draft published on Sep 28, 2012 –  See JSR-339 JCP site jcp.org/en/jsr/detail?id=339 7 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 8.
    JAX-RS 2.0 §  Client API §  Common configuration §  Asynchronous processing §  Filters §  Interceptors §  Hypermedia support §  Server-side content negotiation 8 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 9.
    JAX-RS 2.0 §  Client API §  Common configuration §  Asynchronous processing §  Filters §  Interceptors §  Hypermedia support §  Server-side content negotiation 9 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 10.
    Client API Motivation § HTTP client libraries too low level §  Leveraging providers and concepts from the JAX-RS 1.x API –  E.g., MBRs and MBWs §  Proprietary APIs introduced by major JAX-RS 1.x implementations –  Need for a standard 10 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 11.
    Client API //Get instance of Client Client client = ClientFactory.newClient(); // Get account balance String bal = client.target("http://.../atm/{cardId}/balance") .resolveTemplate("cardId", "111122223333") .queryParam("pin", "9876") .request("text/plain").get(String.class); 11 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 12.
    Client API //Withdraw some money Money mon = client.target("http://.../atm/{cardId}/withdrawal") .resolveTemplate("cardId", "111122223333") .queryParam("pin", "9876") .request("application/json") .post(text("50.0"), Money.class); 12 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 13.
    Client API Invocationinv1 = 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")); 13 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 14.
    Client API Collection<Invocation>invocations = Arrays.asList(inv1, inv2); Collection<Response> responses = Collections.transform( invocations, new F<Invocation, Response>() { public Response apply(Invocation inv) { return inv.invoke(); } }); 14 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 15.
    Client API //Create client and register MyProvider1 Client client = ClientFactory.newClient(); client.configuration().register(MyProvider1.class); // Create atm target; inherits MyProvider1 WebTarget atm = client.target("http://.../atm"); // Register MyProvider2 atm.configuration().register(MyProvider2.class); // Create balance target; inherits MyProvider1, MyProvider2 WebTarget balance = atm.path(”{cardId}/balance"); // Register MyProvider3 balance.configuration().register(MyProvider3.class); 15 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 16.
    JAX-RS 2.0 §  Client API §  Common configuration §  Asynchronous processing §  Filters §  Interceptors §  Hypermedia support §  Server-side content negotiation 16 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 17.
    Common configuration -motivation Client-side client.configuration() .register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .setProperty(“jsonp.callback.name”, “callback”) .setProperty(“jsonp.callback.queryParam”, “true”) ... 17 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 18.
    Common configuration -motivation Server-side public class MyApp extends javax.ws.rs.core.Application { public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<…>(); … classes.add(JsonMessageBodyReader.class); classes.add(JsonMessageBodyWriter.class); classes.add(JsonpInterceptor.class); … return classes; } } 18 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 19.
    Common configuration -solution Client-side client.configuration() .register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .setProperty(“jsonp.callback.name”, “callback”) .setProperty(“jsonp.callback.queryParam”, “true”) ... JsonFeature jf = new JsonFeature().enableCallbackQueryParam(); Client.configuration().register(jf); 19 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 20.
    Common configuration -solution Server-side public Set<Class<?>> getClasses() { … classes.add(JsonMessageBodyReader.class); classes.add(JsonMessageBodyWriter.class); classes.add(JsonpInterceptor.class); … } public Set<Class<?>> getClasses() { … classes.add(JsonFeature.class); … } 20 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 21.
    Common configuration publicinterface Configurable { Map<String, Object> getProperties(); Object getProperty(String name); Configurable setProperties(Map<String, ?> properties); Configurable setProperty(String name, Object value); Collection<Feature> getFeatures(); Set<Class<?>> getProviderClasses(); Set<Object> getProviderInstances(); Configurable register(...); ... } 21 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 22.
    Common configuration publicinterface Feature { boolean configure(Configurable configurable); } 22 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 23.
    A Feature example public void JsonFeature implements Feature { public boolean configure(Configurable config) { config.register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .setProperty(CALLBACK_NAME, calbackName) .setProperty(USE_QUERY_PARAM, useQueryParam); return true; } } 23 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 24.
    Dynamic Feature Server-side only public interface DynamicFeature { void configure(ResourceInfo ri, Configurable configurable); } public interface ResourceInfo { Method getResourceMethod(); Class<?> getResourceClass(); } 24 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 25.
    JAX-RS 2.0 §  Client API §  Common configuration §  Asynchronous processing §  Filters §  Interceptors §  Hypermedia support §  Server-side content negotiation 25 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 26.
    Async Processing § Server API support –  Off-load I/O 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<RESPONSE>, InvocationCallback<RESPONSE>   26 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 27.
    Async Processing: Server-side @Path("/async/longRunning") public class MyResource { @GET public void longRunningOp(@Suspended AsyncResponse ar) { ar.setTimeoutHandler(new MyTimoutHandler()); ar.setTimeout(15, SECONDS); Executors.newSingleThreadExecutor().submit(new Runnable() { public void run() { … ar.resume(result); } }); } } 27 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 28.
    Async Processing: Server-side public interface AsyncResponse { public void resume(Object/Throwable response); public void cancel(); public void cancel(int/Date retryAfter); public boolean isSuspended(); public boolean isCancelled(); public boolean isDone(); public void setTimeout(long time, TimeUnit unit); public void setTimeoutHandler(TimeoutHandler handler); public boolean register(Class<?> callback); public boolean[] register(Class<?> callback, Class<?>... callbacks); public boolean register(Object callback); public boolean[] register(Object callback, Object... callbacks); } 28 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 29.
    Async Processing: Server-side @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Suspended { } public interface TimeoutHandler { void handleTimeout(AsyncResponse asyncResponse); } 29 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 30.
    Async Processing: Server-side public interface ResumeCallback { public void onResume(AsyncResponse resuming, Response response); public void onResume(AsyncResponse resuming, Throwable error); } public interface CompletionCallback { public void onComplete(); public void onError(Throwable throwable); } public interface ConnectionCallback { public void onDisconnect(AsyncResponse disconnected); } 30 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 31.
    Async Processing: Client-side WebTarget target = client.target("http://.../balance”)… // Start async call and register callback Future<?> handle = target.request().async().get( new InvocationCallback<String>() { void complete(String balance) { … } void failed(InvocationException e) { … } }); // After waiting for too long… if (!handle.isDone()) handle.cancel(true); 31 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 32.
    JAX-RS 2.0 §  Client API §  Common configuration §  Asynchronous processing §  Filters §  Interceptors §  Hypermedia support §  Server-side content negotiation 32 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 33.
    Filters & Interceptors Motivation §  Customize JAX-RS request/response processing –  Use Cases: Logging, Compression, Security, Etc. §  Introduced for client and server APIs §  Replace existing proprietary support –  Provided by most JAX-RS 1.x implementations §  All using slightly different types or semantics 33 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 34.
    Filters & Interceptors Filtereach incoming/outgoing message §  Request è Request –  ContainerRequestFilter,   §  Non-wrapping filter chain ClientRequestFilter   –  Filters do not invoke next filter in the chain directly §  Response è Response –  managed by the JAX-RS runtime –  ContainerResponseFilter,   ClientResponseFilter §  Each filter decides to proceed or break the chain §  Server-side specialties –  @PreMatching,  DynamicFeature 34 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 35.
    Filters & Interceptors ALogging Filter Example public class RequestLoggingFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) { log(requestContext); // non-wrapping => returns without invoking the next filter } ... } 35 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 36.
    Filters & Interceptors Interceptentity providers §  Invoked ONLY when/if entity §  MessageBodyReader interceptor processing occurs –  ReaderInterceptor interface –  Performance boost §  MessageBodyWriter interceptor §  Wrapping interceptor chain –  WriterInterceptor interface –  Each interceptor invokes the next one in the chain via context.proceed()   36 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 37.
    Filters & Interceptors AGZip Reader Interceptor Example public class GzipInterceptor implements ReaderInterceptor { @Override Object aroundReadFrom(ReaderInterceptorContext ctx) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); // wrapping => invokes the next interceptor Object entity = ctx.proceed(); ctx.setInputStream(old); return entity; } } 37 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 38.
    Filters & Interceptors write(…) Writer Interceptor … Writer Interceptor MBW Request Filter … Filter Application Transport Network Response Filter … Filter read(…) - optional MBR Reader Interceptor … Reader Interceptor 38 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 39.
    Filters & Interceptors read(…) - optional Reader Interceptor … Reader Interceptor MBR @PreMatching Request Filter Filter Resource Matching Filter … Filter Request Network Application Response Filter … Filter Filter Filter Response write(…) MBW Writer Interceptor … Writer Interceptor 39 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 40.
    Bindings & Priorities §  Binding –  Associating filters and interceptors with resource methods –  Server-side concept §  Priority –  Declaring relative position in the execution chain –  @BindingPriority(int  priority)   §  Shared concept by filters and interceptors Scoped Binding Global Binding Default Static @NameBinding (@Qualifier?) @PreMatching Dynamic DynamicFeature N/A 40 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 41.
    Bindings @NameBinding // or@Qualifier ? @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface Logged {} @Provider @Logged @BindingPriority(USER) public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { … } 41 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 42.
    Bindings @Path("/greet/{name}") @Produces("text/plain") public class MyResourceClass{ @Logged @GET public String hello(@PathParam("name") String name) { return "Hello " + name; } } 42 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 43.
    A DynamicFeature example Server-sideonly public void SecurityFeature implements DynamicFeature { public boolean configure(ResourceInfo ri, Configurable config) { String[] roles = getRolesAllowed(ri); if (roles != null) { config.register(new RolesAllowedFilter(roles)); } } … } 43 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 44.
    JAX-RS 2.0 §  Client API §  Common configuration §  Asynchronous processing §  Filters §  Interceptors §  Hypermedia support §  Server-side content negotiation 44 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 45.
    Hypermedia §  RESTprinciples –  Identifiers and Links –  HATEOAS (Hypermedia As The Engine Of App State) §  Link types: –  Structural Links –  Transitional Links 45 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 46.
    Hypermedia Transitional Links Link: <http://.../orders/1/ship>; rel=ship, <http://.../orders/1/cancel>; rel=cancel ... <order id="1"> <customer>http://.../customers/11</customer> <address>http://.../customers/11/address/1</address> <items> <item> Structural Links <product>http://.../products/111</product> <quantity>2</quantity> </item> <items> ... </order> 46 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 47.
    Hypermedia §  Linkand LinkBuilder classes –  RFC 5988: Web Linking §  Support for Link in ResponseBuilder and filters   –  Transitional links (headers) §  Support for manual structural links –  Via Link.JaxbAdapter & Link.JaxbLink §  Create a resource target from a Link in Client API 47 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 48.
    Hypermedia // ProducerAPI (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(); 48 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 49.
    Hypermedia Response order= client.target(…).request("application/xml").get(); // Consumer API (client-side) Link shipmentLink = order.getLink(“ship”); if (shipmentLink != null) { Response shipment = client.target(shipmentLink).post(null); … } 49 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 50.
    JAX-RS 2.0 §  Client API §  Common configuration §  Asynchronous processing §  Filters §  Interceptors §  Hypermedia support §  Server-side content negotiation 50 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 51.
    Server Side Conneg GET http://.../widgets2 Accept: text/*; q=1 … Path("widgets2") public class WidgetsResource2 { @GET @Produces("text/plain", "text/html") public Widgets getWidget() {...} } 51 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 52.
    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() {...} } 52 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 53.
    JAX-RS 2.0 Summary §  Major new features –  Client API, Filters & Interceptors, Asynchronous Resources, Hypermedia §  Many minor API improvements and extensions –  Request / Response, URI builder, String Converters, @BeanParam, MultivaluedHashMap, GenericType, … §  Improved TCK coverage = improved portability –  ~350 tests in JAX-RS 1.x, ~1700 tests in JAX-RS 2.0 53 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 54.
    <a href=“…” >JAX-RS2.0</a> §  Project web site jax-rs-spec.java.net §  Users mailing list users@jax-rs-spec.java.net §  JSR-339 site jcp.org/en/jsr/detail?id=339 –  Latest specification text draft §  java.net/projects/jax-rs-spec/sources/git/content/spec/spec.pdf –  Latest API snapshot §  jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/index.html 54 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 55.
    <a href=“…” >Jersey2.0</a> §  Project web site jersey.java.net §  Users mailing list users@jersey.java.net –  Latest users guide §  http://jersey.java.net/nonav/documentation/snapshot/index.html –  Latest API documentation §  http://jersey.java.net/nonav/apidocs/snapshot/jersey/index.html 55 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 56.
    56 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 57.
    57 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 58.
    JAX-RS 2.0 §  DI (JSR-330) Integration §  Bean Validation §  Improved Java EE Security Support §  Presentation Layer §  High-level Client API 58 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 59.
    Dependency Injection Integration §  Support Java Dependency Injection API (JSR-330) –  Support  @Inject  and  @Qualifier ? –  @Qualifier  as a replacement for  @NamedBinding  ? –  Provider vs.  ContextResolver ? –  Support DI (JSR-330) or CDI (JSR-299)? §  Issues –  Interference with CDI providers –  EG does not see enough added value for DI §  DI-style injection support deferred 59 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 60.
    Dependency Injection Integration SupportDI (JSR-330) or CDI (JSR-299)? §  Java EE Deployments –  Tight CDI integration makes sense (unification of Java EE component model) §  Java SE Deployments –  DI provides all the required features –  CDI is too heavy-weight §  Many redundant features –  method interceptors, decorators, stereotypes … §  Additional limitations put on managed components 60 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 61.
    Bean Validation § Dropped from JAX-RS 2.0 Public Review –  Difficulty aligning schedules §  Still supported via CDI 1.1 –  JAX-RS resource class must be CDI bean –  BV 1.1 now supports method validation §  May revisit current plan post Java EE 7 61 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 62.
    More Topics… § Improved Java EE security §  High-level client API support –  Hard to design it to be RESTful –  @RolesAllowed, … –  Jersey 2 provides an –  SecurityContext.authenticate(…) experimental support –  Don’t want to end-up with an §  Pluggable Views RPC-style API –  Completes the MVC pattern 62 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.