jax-rs 2.0: restful java on steroids - coding the...

Post on 08-Nov-2018

216 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

JAX-RS 2.0: RESTful Java on Steroids What’s in JSR-339?

Marek Potociar JAX-RS 2.0 Specification Lead Oracle

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

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.

Part I. How we got here…

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

• RESTFul Principles –  Assign everything an ID –  Link things together –  Use common set of methods –  Allow multiple representations –  Stateless communications

Shortest REST Primer Ever

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

•  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

JAX-RS Intro

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

@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)); } …

JAX-RS API

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

@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)); } …

JAX-RS API

Resource path templates

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

@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)); } …

JAX-RS API

Resource path templates

URI parameter injection

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

@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)); } …

JAX-RS API

Resource path templates

URI parameter injection

HTTP method binding

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

@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)); } …

JAX-RS API

Resource path templates

Built-in Serialization

URI parameter injection

HTTP method binding

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

@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); }}

JAX-RS API

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

@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); }}

JAX-RS API

Custom Serialization

Built-in Serialization

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

JAX-RS Most Wanted

Filters Handlers

Validation

Asynchronous Processing

Hypermedia

Server Side Conneg

JSR 330

MVC Client API

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

• 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

JSR 339: JAX-RS 2.0

Part II. Where we are going…

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

New in JAX-RS 2.0

Filters Handlers

Validation

Asynchronous Processing

Hypermedia

Server Side Conneg

JSR 330

MVC Client API

✔ ✔

✔ ✔

✔ ✔

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

Client API

Filters Handlers

Validation

Asynchronous Processing

Hypermedia

Server Side Conneg

JSR 330

Client API

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

• 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

Client API

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

Client API

Client Resource Target “atm”

Request Builder

Resource Target “{cardId}”

Resource Target “balance”

Resource Target “withdrawal”

Client Factory

Response

Invocation

Configuration Configuration Configuration

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

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

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

Client API

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

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

Client API

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

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"));

Client API

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

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(); } });

Client API

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

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

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

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

Client API

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

Filters & Handlers

Filters Handlers

Validation

Asynchronous Processing

Hypermedia

Server Side Conneg

JSR 330

Client API

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

• 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

Filters & Handlers

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

• 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

Filters & Handlers

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

@Providerclass LoggingFilter implements RequestFilter, ResponseFilter {

// RequestFilter implementation @Override public FilterAction preFilter(FilterContext ctx) throws IOException { logRequest(ctx.getRequest()); return FilterAction.NEXT; }

Filters & Handlers

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

// ResponseFilter implementation @Override public FilterAction postFilter(FilterContext ctx) throws IOException { logResponse(ctx.getResponse()); return FilterAction.NEXT; }

}

Filters & Handlers

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

• 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

Filters & Handlers

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

@Providerclass 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(); } }

Filters & Handlers

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

• Associating filters and handlers with resources • Declaring relative position in the chain

–  @BindingPriority(priority)

•  Same mechanism for filters and handlers

Filters & Handlers Bindings

Name Binding Global Binding

Static @NameBinding / @Qualifier ? DEFAULT

Dynamic DynamicBinding interface DynamicBinding interface

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

@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 { … }

Filters & Handlers Bindings

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

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

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

Filters & Handlers Bindings

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

Validation

Filters Handlers

Validation

Asynchronous Processing

Hypermedia

Server Side Conneg

JSR 330

Client API

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

•  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

Validation

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

@Path("/")class MyResourceClass {

@POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public void registerUser( @NotNull @FormParam("firstName") String firstName, @NotNull @FormParam("lastName") String lastName, @Email @FormParam("email") String email) { ... } }

Validation

Built-in

Custom

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

@Target({ METHOD, FIELD, PARAMETER })@Retention(RUNTIME)@Constraint(validatedBy = EmailValidator.class)public @interface Email { ... }

class EmailValidator implements ConstraintValidator<Email, String> { public void initialize(Email email) { … } public boolean isValid(String value, ConstraintValidatorContext context) { // Check 'value' is e-mail address … }}

Validation

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

@ValidationAclass 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) { … } }

Validation

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

Async Processing

Filters Handlers

Validation

Asynchronous Processing

Hypermedia

Server Side Conneg

JSR 330

Client API

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

•  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<RESPONSE>, InvocationCallback<RESPONSE>

Async Processing

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

@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!"); } }); }}

Async Processing

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

@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(); // Suspend connection and return }}

Async Processing

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

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

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

// After waiting for a while …if (!handle.isDone()) handle.cancel(true);

Async Processing

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

Hypermedia

Filters Handlers

Validation

Asynchronous Processing

Hypermedia

Server Side Conneg

JSR 330

Client API

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

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

• Link types: –  Structural Links –  Transitional Links

Hypermedia

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

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> <product>http://.../products/111</product> <quantity>2</quantity> </item> <items> ... </order>

Hypermedia

Transitional Links

Structural Links

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

• Transitional Links Only • Link and LinkBuilder classes

–  RFC 5988: Web Linking

•  Support for Link in ResponseBuilder • Create Target from Link in Client API

Hypermedia

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

// 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();

Hypermedia

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

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(…); … }

Hypermedia

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

Other Topics

Filters Handlers

Validation

Asynchronous Processing

Hypermedia

Server Side Conneg

JSR 330

Client API …

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

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

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

Server Side Conneg

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

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

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

Server Side Conneg

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

• 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 ?

Other Topics

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)

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

Filters & Handlers

Req/Resp

Filter Resource Matching Filter … Filter Filter …

Filter Filter … Filter

MBR/W

Handler

Handler

MBR/W

Handler

Handler

MBR/W

Handler

Handler

Request

Response

top related