may 2010 - resteasy

37
RESTEasy Dessì Massimiliano Jug Meeting Cagliari 29 maggio 2010

Upload: jbug-italy

Post on 10-May-2015

3.910 views

Category:

Technology


0 download

DESCRIPTION

RestEasy - Massimiliano Dessì Jug Sardegna - JBoss User Group Roma 29/05/2010 - Cagliari

TRANSCRIPT

Page 1: May 2010 - RestEasy

RESTEasy

Dessì Massimiliano

Jug Meeting Cagliari 29 maggio 2010

Page 2: May 2010 - RestEasy

Software Architect and EngineerProNetics / Sourcesense

Presidente JugSardegna Onlus

Fondatore e coordinatoreSpringFramework Italian User Group

Committer - ContributorOpenNMS - MongoDB - MagicBox

AutoreSpring 2.5 Aspect Oriented Programming

Author

Page 3: May 2010 - RestEasy

* 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

REST

Page 4: May 2010 - RestEasy

http://www.fruits.com/products/134

http://www.fruits.com/customers/146

http://www.fruits.com/orders/135

http://www.fruits.com/shipments/2468

Addressability

Page 5: May 2010 - RestEasy

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

Page 6: May 2010 - RestEasy

JSON XML YAML

...

Content-Type:

text/plain

text/html

application/xml

text/html;

charset=iso-8859-1....

Representation Oriented

Page 7: May 2010 - RestEasy

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

Stateless communication

Page 8: May 2010 - RestEasy

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> ...

HATEOAS

Page 9: May 2010 - RestEasy

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}

URI != RPC

Page 10: May 2010 - RestEasy

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>

Read - HTTP GET

Page 11: May 2010 - RestEasy

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

}

Read - HTTP GET - RESTEasy way

Page 12: May 2010 - RestEasy

POST /orders HTTP/1.1

Content-Type: application/xml <order> <total>€150.20</total>

<date>June 22, 2010 10:30</date> ... </order>

Create - HTTP POST

Page 13: May 2010 - RestEasy

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

Create - HTTP POST – RESTEasy Way

Page 14: May 2010 - RestEasy

PUT /orders/232 HTTP/1.1

Content-Type: application/xml <product id="444"> <name>HTC Desire</name> <cost>€450.00</cost> </product>

Update - HTTP PUT

Page 15: May 2010 - RestEasy

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

}

Update - HTTP PUT - RESTEasy Way

Page 16: May 2010 - RestEasy

DELETE /orders/232 HTTP/1.1

Delete - HTTP DELETE

Page 17: May 2010 - RestEasy

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

@DELETE public void delete(@PathParam("id") int id) {

db.delete(id); }

Delete - HTTP DELETE -RESTEasy way

Page 18: May 2010 - RestEasy

@Consumes("text/xml")

@Produces("application/json")

@Produces("text/*")

...

Content Negotiation

Page 19: May 2010 - RestEasy

@PathParam

@QueryParam

@HeaderParam

@MatrixParam

@CookieParam

@FormParam

@Form

@Encoded

@Context

Annotations available

Page 20: May 2010 - RestEasy

The best is yet to come :)

Interceptors like Servlet Filter and AOP

Asynchronous calls

Asynchronous Job

GZIP compression

Page 21: May 2010 - RestEasy

Interceptors

public interface MessageBodyReaderInterceptor { Object read(MessageBodyReaderContext context) throws IOException, WebApplicationException; }

public interface MessageBodyWriterInterceptor { void write(MessageBodyWriterContext context) throws IOException, WebApplicationException; }

Page 22: May 2010 - RestEasy

Interceptors

public interface PreProcessInterceptor {ServerResponse preProcess(HttpRequest req, ResourceMethod method)

throws Failure, WebApplicationException; }

public interface PostProcessInterceptor { void postProcess(ServerResponse response); }

Page 23: May 2010 - RestEasy

Interceptors

public interface ClientExecutionInterceptor {ClientResponse execute(ClientExecutionContext ctx)

throws Exception; }

public interface ClientExecutionContext { ClientRequest getRequest(); ClientResponse proceed() throws Exception; }

Page 24: May 2010 - RestEasy

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

Page 25: May 2010 - RestEasy

Interceptors

@Provider @ServerInterceptor public class MyHeaderDecorator implements

MessageBodyWriterInterceptor { public void write(MessageBodyWriterContext context)

throws IOException, WebApplicationException{context.getHeaders().add("My-Header", "custom"); context.proceed();

}

}

Page 26: May 2010 - RestEasy

Interceptors

@Provider @ServerInterceptor @ClientInterceptor @Precedence("ENCODER") public class MyCompressionInterceptor

implements MessageBodyWriterInterceptor { … }

Page 27: May 2010 - RestEasy

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

Page 28: May 2010 - RestEasy

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

@GET @Produces("application/xml") @GZIP public String getFooData() {

.. }

@GZIP

Page 29: May 2010 - RestEasy

@Cache maxAge sMaxAge noStore noTransform mustRevalidate proxyRevalidate isPrivate

@NoCache

@CACHE

Page 30: May 2010 - RestEasy

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

Page 31: May 2010 - RestEasy

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>

Page 32: May 2010 - RestEasy

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>

Page 33: May 2010 - RestEasy

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"/>

Page 34: May 2010 - RestEasy

RESTEasy With Springimport 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")@Controllerpublic class FrontController {

@GET @Path("/{id}") @Produces(MediaType.TEXT_HTML) public ModelAndView getData(@PathParam("id") String collectionId) {

.... }

Page 35: May 2010 - RestEasy

Other Features

ATOM supportJSON support

Client FrameworkMultipart Providers

YAML ProviderJAXB providersAuthenticationEJB IntegrationSeam Integration

Guice 2.0 IntegrationJBoss 5.x Integration

Page 36: May 2010 - RestEasy

Q & A

Page 37: May 2010 - RestEasy

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

Thanks for your attention!