RESTEasy




 Dessì Massimiliano

 Jug Meeting Cagliari
   29 maggio 2010
Author
    Software Architect and Engineer
        ProNetics / Sourcesense

              Presidente
          JugSardegna...
REST
               * Addressable resources *
       Each resource must be addressable via a URI

            * Uniform, c...
Addressability




 http://www.fruits.com/products/134
http://www.fruits.com/customers/146
  http://www.fruits.com/orders/...
Uniform, Constrained Interface


GET read-only idempotent and safe (not change the server state)

               PUT inser...
Representation Oriented



     JSON XML YAML
          ...


     Content-Type:
      text/plain
       text/html
    app...
Stateless communication




no client session data stored on the server
     it should be held and maintained
       by th...
HATEOAS

           Hypermedia is a document-centric approach
                 hypermedia and hyperlinks as sets
         ...
URI != RPC



http://www.fruits.com/orders
http://www.fruits.com/orders/{id}
http://www.fruits.com/products
http://www.fru...
Read - HTTP GET
GET /orders?index=0&size=15 HTTP/1.1
GET /products?index=0&size=15 HTTP/1.1
GET /customers?index=0&size=15...
Read - HTTP GET - RESTEasy way

@Path("/orders")
public class OrderController {

  @GET
  @Path("/{id}")
  @Produces("appl...
Create - HTTP POST



POST /orders HTTP/1.1
Content-Type: application/xml
<order>
   <total>€150.20</total>
   <date>June ...
Create - HTTP POST – RESTEasy Way

@Path("/customers")
public class CustomerController {


@POST
@Consumes("application/xm...
Update - HTTP PUT



PUT /orders/232 HTTP/1.1
Content-Type: application/xml
<product id="444">
    <name>HTC Desire</name>...
Update - HTTP PUT - RESTEasy Way


@Path("/customers")
public class CustomerController {

 @PUT
 @Path("{id}")
 @Consumes(...
Delete - HTTP DELETE




DELETE /orders/232 HTTP/1.1
Delete - HTTP DELETE -RESTEasy way




    @Path("/customers")
    public class CustomerController {

         @Path("{id}...
Content Negotiation




   @Consumes("text/xml")
@Produces("application/json")
    @Produces("text/*")
          ...
Annotations available

     @PathParam
    @QueryParam
    @HeaderParam
    @MatrixParam
    @CookieParam
     @FormParam
...
The best is yet to come :)




Interceptors like Servlet Filter and AOP

          Asynchronous calls

          Asynchron...
Interceptors


public interface MessageBodyReaderInterceptor {
     Object read(MessageBodyReaderContext    context)
     ...
Interceptors



public interface PreProcessInterceptor {
      ServerResponse preProcess(HttpRequest req,
      ResourceMe...
Interceptors



public interface ClientExecutionInterceptor {
    ClientResponse execute(ClientExecutionContext ctx)
     ...
Interceptors


public interface MessageBodyReaderInterceptor {
     Object read(MessageBodyReaderContext    context)
     ...
Interceptors



@Provider
@ServerInterceptor
public class MyHeaderDecorator implements
                          MessageBo...
Interceptors



 @Provider
 @ServerInterceptor
 @ClientInterceptor
 @Precedence("ENCODER")
 public class MyCompressionInte...
Asynchronous Job

         RESTEasy Asynchronous Job Service
                is an implementation of
             the Asyn...
@GZIP


@Consumes("application/xml")
@PUT
public void put(@GZIP Customer customer){
  …
}



@GET
@Produces("application/x...
@CACHE


  @Cache
    maxAge
    sMaxAge
    noStore
  noTransform
 mustRevalidate
proxyRevalidate
   isPrivate




  @NoC...
Asyncronous
@GET
@Path("basic")
@Produces("text/plain")
public void getBasic(final @Suspend(10000) AsynchronousResponse re...
WEB.XML

<servlet>
    <servlet-name>
        Resteasy
    </servlet-name>
    <servlet-class>
  org.jboss.resteasy.plugin...
RESTEasy With Spring
             Without SpringDispatcherServlet/SpringMVC


<listener>
    <listener-class>
       org.r...
RESTEasy With Spring
              With SpringDispatcherServlet/SpringMVC
 <servlet>
    <servlet-name>Resteasy</servlet-n...
RESTEasy With Spring
import   javax.ws.rs.GET;
import   javax.ws.rs.Path;
import   javax.ws.rs.PathParam;
import   javax.w...
Other Features


      ATOM support
      JSON support
   Client Framework
 Multipart Providers
     YAML Provider
    JAX...
Q&A
Thanks for your attention!

       Massimiliano Dessì
       desmax74 at yahoo.it
  massimiliano.dessi at pronetics.it

  ...
Upcoming SlideShare
Loading in …5
×

RESTEasy

3,797 views

Published on

RESTEasy slides may 2010

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,797
On SlideShare
0
From Embeds
0
Number of Embeds
502
Actions
Shares
0
Downloads
67
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

RESTEasy

  1. 1. RESTEasy Dessì Massimiliano Jug Meeting Cagliari 29 maggio 2010
  2. 2. Author Software Architect and Engineer ProNetics / Sourcesense Presidente JugSardegna Onlus Fondatore e coordinatore SpringFramework Italian User Group Committer - Contributor OpenNMS - MongoDB - MagicBox Autore Spring 2.5 Aspect Oriented Programming
  3. 3. REST * Addressable resources * Each resource must be addressable via a URI * Uniform, constrained interface * Http methods to manipulate resources * Representation-oriented * Interact with representations of the service (JSON,XML,HTML) * Stateless communication * * Hypermedia As The Engine Of Application State * data formats drive state transitions in the application
  4. 4. Addressability http://www.fruits.com/products/134 http://www.fruits.com/customers/146 http://www.fruits.com/orders/135 http://www.fruits.com/shipments/2468
  5. 5. Uniform, Constrained Interface GET read-only idempotent and safe (not change the server state) PUT insert or update idempotent DELETE idempotent POST nonidempotent and unsafe HEAD like GET but return response code and headers OPTIONS information about the communication options
  6. 6. Representation Oriented JSON XML YAML ... Content-Type: text/plain text/html application/xml text/html; charset=iso-8859-1 ....
  7. 7. Stateless communication no client session data stored on the server it should be held and maintained by the client and transferred to the server with each request as needed The server only manages the state of the resources it exposes
  8. 8. HATEOAS Hypermedia is a document-centric approach hypermedia and hyperlinks as sets of information from disparate sources <order id="576"> <customer>http://www.fruits.com/customers/146</customer> <order-entries> <order-entry> <quantity>7</quantity> <product>http://www.fruits.com/products/113</product> ...
  9. 9. URI != RPC http://www.fruits.com/orders http://www.fruits.com/orders/{id} http://www.fruits.com/products http://www.fruits.com/products/{id} http://www.fruits.com/customers http://www.fruits.com/customers/{id}
  10. 10. Read - HTTP GET GET /orders?index=0&size=15 HTTP/1.1 GET /products?index=0&size=15 HTTP/1.1 GET /customers?index=0&size=15 HTTP/1.1 GET /orders/189 HTTP/1.1 HTTP/1.1 200 OK Content-Type: application/xml <order id="189"> ... </order>
  11. 11. Read - HTTP GET - RESTEasy way @Path("/orders") public class OrderController { @GET @Path("/{id}") @Produces("application/xml") public StreamingOutput getCustomer(@PathParam("id") int id) { final Order order = DBOrders.get(id); if (order == null) { throw new WebApplicationException(Response.Status.NOT_FOUND); } return new StreamingOutput() { public void write(OutputStream outputStream) throws IOException, WebApplicationException { outputOrder(outputStream, order); } }; }
  12. 12. Create - HTTP POST POST /orders HTTP/1.1 Content-Type: application/xml <order> <total>€150.20</total> <date>June 22, 2010 10:30</date> ... </order>
  13. 13. Create - HTTP POST – RESTEasy Way @Path("/customers") public class CustomerController { @POST @Consumes("application/xml") public Response createCustomer(InputStream is) { Customer customer = readCustomerFromStream(is); customer.setId(idCounter.getNext()); DB.put(customer); StringBuilder sb = new StringBuilder("/customers/"). append(customer.getId()); return Response.created(URI.create(sb.toString()).build(); }
  14. 14. Update - HTTP PUT PUT /orders/232 HTTP/1.1 Content-Type: application/xml <product id="444"> <name>HTC Desire</name> <cost>€450.00</cost> </product>
  15. 15. Update - HTTP PUT - RESTEasy Way @Path("/customers") public class CustomerController { @PUT @Path("{id}") @Consumes("application/xml") public void updateCustomer(@PathParam("id") int id,InputStream is){ Customer update = readCustomerFromStream(is); Customer current = DB.get(id); if (current == null) throw new WebApplicationException(Response.Status.NOT_FOUND); current.setFirstName(update.getFirstName()); … DB.update(current); }
  16. 16. Delete - HTTP DELETE DELETE /orders/232 HTTP/1.1
  17. 17. Delete - HTTP DELETE -RESTEasy way @Path("/customers") public class CustomerController { @Path("{id}") @DELETE public void delete(@PathParam("id") int id) { db.delete(id); }
  18. 18. Content Negotiation @Consumes("text/xml") @Produces("application/json") @Produces("text/*") ...
  19. 19. Annotations available @PathParam @QueryParam @HeaderParam @MatrixParam @CookieParam @FormParam @Form @Encoded @Context
  20. 20. The best is yet to come :) Interceptors like Servlet Filter and AOP Asynchronous calls Asynchronous Job GZIP compression
  21. 21. Interceptors public interface MessageBodyReaderInterceptor { Object read(MessageBodyReaderContext context) throws IOException, WebApplicationException; } public interface MessageBodyWriterInterceptor { void write(MessageBodyWriterContext context) throws IOException, WebApplicationException; }
  22. 22. Interceptors public interface PreProcessInterceptor { ServerResponse preProcess(HttpRequest req, ResourceMethod method) throws Failure, WebApplicationException; } public interface PostProcessInterceptor { void postProcess(ServerResponse response); }
  23. 23. Interceptors public interface ClientExecutionInterceptor { ClientResponse execute(ClientExecutionContext ctx) throws Exception; } public interface ClientExecutionContext { ClientRequest getRequest(); ClientResponse proceed() throws Exception; }
  24. 24. Interceptors public interface MessageBodyReaderInterceptor { Object read(MessageBodyReaderContext context) throws IOException, WebApplicationException; } public interface MessageBodyWriterInterceptor { void write(MessageBodyWriterContext context) throws IOException, WebApplicationException; } public interface PreProcessInterceptor { ServerResponse preProcess(HttpRequest req, ResourceMethod method) throws Failure, WebApplicationException; }
  25. 25. Interceptors @Provider @ServerInterceptor public class MyHeaderDecorator implements MessageBodyWriterInterceptor { public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException{ context.getHeaders().add("My-Header", "custom"); context.proceed(); } }
  26. 26. Interceptors @Provider @ServerInterceptor @ClientInterceptor @Precedence("ENCODER") public class MyCompressionInterceptor implements MessageBodyWriterInterceptor { … }
  27. 27. Asynchronous Job RESTEasy Asynchronous Job Service is an implementation of the Asynchronous Job pattern defined in O'Reilly's "Restful Web Services" Use: /asynch/jobs/{job-id}?wait={millisconds}|nowait=true Fire and forget http://example.com/myservice?oneway=true
  28. 28. @GZIP @Consumes("application/xml") @PUT public void put(@GZIP Customer customer){ … } @GET @Produces("application/xml") @GZIP public String getFooData() { .. }
  29. 29. @CACHE @Cache maxAge sMaxAge noStore noTransform mustRevalidate proxyRevalidate isPrivate @NoCache
  30. 30. Asyncronous @GET @Path("basic") @Produces("text/plain") public void getBasic(final @Suspend(10000) AsynchronousResponse res) throws Exception{ Thread t = new Thread() { @Override public void run(){ try{ Response jaxrs = Response.ok("basic").type(MediaType.TEXT_PLAIN).build(); res.setResponse(jaxrs); }catch (Exception e) { e.printStackTrace(); } } }; t.start(); }
  31. 31. WEB.XML <servlet> <servlet-name> Resteasy </servlet-name> <servlet-class> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher </servlet-class> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
  32. 32. RESTEasy With Spring Without SpringDispatcherServlet/SpringMVC <listener> <listener-class> org.resteasy.plugins.server.servlet.ResteasyBootstrap </listener-class> </listener> <listener> <listener-class> org.resteasy.plugins.spring.SpringContextLoaderListener </listener-class> </listener> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
  33. 33. RESTEasy With Spring With SpringDispatcherServlet/SpringMVC <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>Spring</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> Import in your bean's definition <beans xmlns="http://www.springframework.org/schema/beans" ... <import resource="classpath:springmvc-resteasy.xml"/>
  34. 34. RESTEasy With Spring import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; ... import org.springframework.stereotype.Controller; @Path("rest/services") @Controller public class FrontController { @GET @Path("/{id}") @Produces(MediaType.TEXT_HTML) public ModelAndView getData(@PathParam("id") String collectionId) { .... }
  35. 35. Other Features ATOM support JSON support Client Framework Multipart Providers YAML Provider JAXB providers Authentication EJB Integration Seam Integration Guice 2.0 Integration JBoss 5.x Integration
  36. 36. Q&A
  37. 37. Thanks for your attention! Massimiliano Dessì desmax74 at yahoo.it massimiliano.dessi at pronetics.it http://twitter.com/desmax74 http://jroller.com/desmax http://www.linkedin.com/in/desmax74 http://www.slideshare.net/desmax74 http://wiki.java.net/bin/view/People/MassimilianoDessi http://www.jugsardegna.org/vqwiki/jsp/Wiki?MassimilianoDessi

×