REST con Jersey

26
REST con Jersey Fabio Bonfante [email protected]

description

Un'introduzione pragmatica a REST e al suo utilizzo con Jersey

Transcript of REST con Jersey

Page 1: REST con Jersey

JAX-RS with Jersey

REST con Jersey

Fabio Bonfante

[email protected]

Page 2: REST con Jersey

JAX-RS with Jersey

Cosa vuol dire REST

“Representational State Transfer”

chiaro no?

Page 3: REST con Jersey

JAX-RS with Jersey

Definizione di REST

● Fielding, Roy Thomas (2000), “Architectural Styles and the Design of Network-based Software Architectures”

MA

● Ognuno ormai ha la sua “definizione”

Page 4: REST con Jersey

JAX-RS with Jersey

Un'idea (forse) comune

● Software architectural style● Ogni cosa e' una risorsa e ha un identificativo

(tipicamente un URL)● Server (il più possibile) senza stato● Applicata soprattutto per i web-services

(SOAP non ci piace più)● Sfrutta meglio il protocollo HTTP

(vedi PUT e DELETE questi “sconosciuti”)● Benvenuto JSON

Page 5: REST con Jersey

JAX-RS with Jersey

Un esempio di API REST

Page 6: REST con Jersey

JAX-RS with Jersey

Un esempio di API REST

POSTcreate

GETread

PUTupdate

DELETEdelete

/dogsNuovo cane

Lista di tutti i cani

Aggiornamento massivo

Cancellazione di tutti i cani

/dogs/313 3rR0rMostra “Pluto”

Se esiste, aggiorna Pluto

Cancella Pluto

Page 7: REST con Jersey

JAX-RS with Jersey

REST con Jersey

● Specifica JAX-RSThe Java API for RESTful Web Services (JSR-311)

● Implementazione di riferimento● Versioni

– 1.18 (legacy...)

– 2.x (attualmente 2.9)

Page 8: REST con Jersey

JAX-RS with Jersey

Jersey: la ragion d'essere

● Mapping chiamate HTTP a metodi di oggetti POJO

● Restituire nel formato richiesto:– Content-type negotiation (Es. XML, JSON,....)

Page 9: REST con Jersey

JAX-RS with Jersey

Jersey overview

● Deployment– Web container: Servlet 2.x e 3.x, filter

– HTTP Server

– JEE, OSGI

● Configurazione tramite:– JAX-RS class: Application

– Jersey class ResourceConfig

● JAX-RS Client + connectors:– Apache HTTP, Jetty, Grizzly Asynchronous

● Test Framework (no JAX-RS)

Page 10: REST con Jersey

JAX-RS with Jersey

Mapping: annotazioni base

● @Path("/dogs”)● @GET, @PUT, @POST, @DELETE● @Produces, @Consumes

– @Produces("application/json")– @Produces({"application/xml",

"application/json"})

Page 11: REST con Jersey

JAX-RS with Jersey

Mapping: parametri

● @PathParam– @Path("/users/{username}")– @Path("users/{username: [a-zA-Z][a-zA-Z_0-9]*}")

● @QueryParam– GET http://example.com/dogs?limit=100

● @FormParam

@POST

@Consumes("application/x-www-form-urlencoded")

public void post(@FormParam("name") String name) {

// Store the message

}

Page 12: REST con Jersey

JAX-RS with Jersey

Support JSON

● Varie librerie:– MOXy (jersey 2.x preferred)– Jackson– Jettison– Java API for JSON Processing (JSON-P)

● Modalità– POJO based JSON binding (MOXy and Jackson)– JAXB based JSON binding – Low-level JSON parsing & processing

(Jettison, e JSON Processing API da JEE7+)

Page 13: REST con Jersey

JAX-RS with Jersey

Supporto JSON – MOXy

<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-moxy</artifactId> <version>2.9</version></dependency>

● Autodiscover se presente nel classpath● Supporta anche XML con annotazioni JAXB

Page 14: REST con Jersey

JAX-RS with Jersey

Supporto JSON – Jackson

<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.9</version></dependency>

● Va registrato tra le features di Jersey● Va configurato un ObjectMapper● Dicono che forse è il più veloce...

Page 15: REST con Jersey

JAX-RS with Jersey

Supporto XML

– javax.xml.transform.stream.StreamSource

– javax.xml.transform.stream.SAXSource

– javax.xml.transform.stream.DOMSource– org.w3c.dom.Document

● JAXBElement<MyBean>Se non voglio usare @XmlRootElement

Page 16: REST con Jersey

JAX-RS with Jersey

Ricezione multipart<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>2.9</version></dependency>

Da registrare esplicitamente in Jersey

@PUT @Path("{id}/image")@Consumes(MediaType.MULTIPART_FORM_DATA)

public String setImage( @PathParam("id") Long id, @FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail) {

return saveImage(uploadedInputStream);

}

Page 17: REST con Jersey

JAX-RS with Jersey

Dependency Injection

<dependency> <groupId>org.glassfish.jersey.ext</groupId> <artifactId>jersey-spring3</artifactId> <version>2.9</version></dependency>

● Bean Spring come risorse e provider Jersey● Iniettare in Jersey bean di Spring (non da XML!)

Il ciclo di vita delle risorse Jersey è

gestito da Jersey

Page 18: REST con Jersey

JAX-RS with Jersey

Gestione eccezioni

Facebook

HTTP Status Code: 200

{"type" : "OauthException", "message":"(#803) Some of the

aliases you requested do not exist: foo.bar"}

Twilio

HTTP Status Code: 401

{"status" : "401", "message":"Authenticate","code": 20003, "more

info": "http://www.twilio.com/docs/errors/20003"}

SimpleGeo

HTTP Status Code: 401

{"code" : 401, "message": "Authentication Required"}

Page 19: REST con Jersey

JAX-RS with Jersey

Gestione eccezioni

@Provider

public class AppExceptionMapper implements ExceptionMapper<AppException> {

@Override public Response toResponse(AppException ex) {

return ResponseBuilder.userException(ex);

}

Page 20: REST con Jersey

JAX-RS with Jersey

REST best practices

● Risorse: nomi (meglio concreti) e non verbi● Associazioni:

– GET /owners/5678/dogs

GET /dogs/byOwner/5678

oppure GET /dogs/?owner=5678

MOLTO MEGLIO!!!

ma... perchè?

Page 21: REST con Jersey

JAX-RS with Jersey

REST best practices

● E' complicato con Jersey gestire le risorse gerarchicamente

● I client si aspettano che: “/owners/....” restituisca degli “Owners”

● È un concetto assimilabile ai Dao che già conosciamo● Permette di nascondere la complessità sotto ‘?’

“Da una Risorsa derivano (grandi)oggetti di quel tipo!”

Page 22: REST con Jersey

JAX-RS with Jersey

EXTRA: REST best practices

● Mai rilasciare un API senza versione!● Operazioni puramente funzionali:

– /convert?from=EUR&to=CNY&amount=100

– Usare VERBI – Documentare che NON sono risorse

● Sottodominio specifico per le API● ChattyAPIs: quante chiamate servono?● Occhio alle gerarchie di Resources

Page 23: REST con Jersey

JAX-RS with Jersey

Perchè ci/mi piace REST

● Lato server– Mapping chiaro funzioni esposte– Scalabilità se gestito bene lo stato

● Lato client web– Librerie JS con concetto resource (es.

AngularJS)– JSON “nativo” nei browser– Più dinamicità ed efficienza nei client

Page 24: REST con Jersey

JAX-RS with Jersey

Perchè mi piace REST

● Lato client mobile– JSON piu' leggero di XML– HTTP Tools che parlano

● Integrazione – Più semplice (bastano “curl” o “wget” da shell)– Servizi più raggiungibili (evviva la porta 80!!!)– Aggregazione di servizi da provider diversi per

creare innovazione– Monetizzazione della propria Business Logic

Page 26: REST con Jersey

JAX-RS with Jersey

Chi RESTa per la

?