C DI, S eam & R E S TE as y You havent seen RES T yet! Dan - - PowerPoint PPT Presentation

c di s eam r e s te as y you haven t seen res t yet
SMART_READER_LITE
LIVE PREVIEW

C DI, S eam & R E S TE as y You havent seen RES T yet! Dan - - PowerPoint PPT Presentation

C DI, S eam & R E S TE as y You havent seen RES T yet! Dan Allen S enior S oftware Engineer JBoss, by Red Hat Ag enda R E S T princ iples JAX -R S S eam R E S TE as y integ ration JAX -R S enhanc ed w ith C DI Demo Abus ing H TTP


slide-1
SLIDE 1

C DI, S eam & R E S TE as y You haven’t seen RES T yet!

Dan Allen S enior S oftware Engineer JBoss, by Red Hat

slide-2
SLIDE 2

Ag enda

R E S T princ iples JAX -R S S eam R E S TE as y integ ration JAX -R S enhanc ed w ith C DI Demo

slide-3
SLIDE 3

Abus ing H TTP w ith S OAP

slide-4
SLIDE 4

R E S T to the res c ue

Web S ervic e Web

slide-5
SLIDE 5

S taying g rounded w ith R E S T

S imple Lig htw eig ht Hig h performanc e

slide-6
SLIDE 6

S imple ing redients of the Web

HTTP applic ation protoc ol U R I naming s tandard X M L markup lang uag e

(and alternatives)

slide-7
SLIDE 7

A tale of tw o w ebs

B row s able w eb Prog rammable w eb

HTML + images + CSS, etc XML (or JSON)

Document

slide-8
SLIDE 8

E very w eb s ite is a s ervic e

slide-9
SLIDE 9

E nabling automation

slide-10
SLIDE 10

R E S T, s pelled out

R E pres entational S tate Trans fer

slide-11
SLIDE 11

R E S Tful arc hitec tural princ iples

Addres s able res ourc es U niformed, c ons trained interfac e R epres entation-oriented S tateles s c ommunic ation

slide-12
SLIDE 12

Addres s able res ourc es

U R I for every res ourc e in s ys tem R es ourc e reac hable by unique ID Provides s c oping information

– Query string used to narrow result set

S tepping s tones

– Makes it possible to link (linkability) – Allows disparate applications to interact

http://socialize.com/rest/updates/311 http://socialize.com/rest/updates/311

slide-13
SLIDE 13

U niformed, c ons trained interfac e

Protoc ol method == operation

– 4 HTTP methods: GET, PUT, DELETE, POS T

An arc hitec ture bas ed on 4 methods ?

– SQL (SELECT, INSERT, UPDATE, DELETE) – JMS (send, receive)

slide-14
SLIDE 14

HTTP methods

G E T - read only, idempotent and s afe PU T - ins ert or update, idempotent DE LE TE - remove s ervic es , idempotent POS T - NOT idempotent NOR uns afe

– constraints are relaxed for flexibility

slide-15
SLIDE 15

R epres entation-oriented

Data has a repres entation

– Negotiated between client and server

HTTP w as des ig ned for this purpos e C lient – “I would prefer...”

– Accept (MIME type) – Accept-Language – Accept-Encoding

S erver – “Here's what I'll give you...”

– Content-type header (MIME type)

slide-16
SLIDE 16

S tateles s c ommunic ation

M ore s c alable

– GET lends itself well to caching

C lient maintains s tate Takes burden off s erver

slide-17
SLIDE 17

R es pec t the medium

R eques t

– HTTP method – URI – Request headers – Entity body

R es pons e

– HTTP response code – Response headers – Entity body

slide-18
SLIDE 18

What do you need to R E S T?

HTTP c lient (browser, bot, smart phone) HTTP s erver that s peaks R E S T

JAX -R S

slide-19
SLIDE 19

JS R -311: JAX -R S

Java APIs for developing Web S ervic es follow ing the R E S T arc hitec tural s tyle S erved via an HTTP s ervlet G oals :

– POJO-based (annotations) – HTTP-centric – Format independent (MIME type) – Container independent – Inclusion in Java EE 5+

slide-20
SLIDE 20

http://socialize.com/rest/timeline http://socialize.com/rest/timeline

Our firs t R E S T res ourc e

slide-21
SLIDE 21

@Path("/timeline") public class TimelineService { @GET public String getUpdates() { return "<updates><update>...</update></updates>"; } } @Path("/timeline") public class TimelineService { @GET public String getUpdates() { return "<updates><update>...</update></updates>"; } }

Our firs t JAX -R S res ourc e

slide-22
SLIDE 22

How it w orks

R E S T S ervlet handles G E T reques t Ins tanc e of TimelineS ervic e is c reated @G E T method c alled R eturn value s ent as res pons e R es ourc e ins tanc e throw n aw ay

JAX-RS component model is intentionally simple!

slide-23
SLIDE 23

http://socialize.com/rest/timeline?count=25 http://socialize.com/rest/timeline?count=25

Throttling the res pons e

slide-24
SLIDE 24

@Path("/timeline") public class TimelineService { @GET public String getUpdates(@QueryParam("count") @DefaultValue("50") int count) { ... } } @Path("/timeline") public class TimelineService { @GET public String getUpdates(@QueryParam("count") @DefaultValue("50") int count) { ... } }

Ac c epting a query parameter

http://socialize.com/rest/timeline http://socialize.com/rest/timeline http://socialize.com/rest/timeline?count=50 http://socialize.com/rest/timeline?count=50

slide-25
SLIDE 25

Parameter types

@QueryParam – Query s tring @HeaderParam – HTTP header @C ookieParam – HTTP c ookie @FormParam – Form input @PathParam – U R I path @M atrixParam – M atrix U R I s eg ment

slide-26
SLIDE 26

S tepping into a s ub-res ourc e

http://socialize.com/rest/timeline/mojavelinux http://socialize.com/rest/timeline/mojavelinux

slide-27
SLIDE 27

@Path("/timeline") public class TimelineService { @GET @Path("/{username}") public String getUpdates(@PathParam("username") String u) { ... } } @Path("/timeline") public class TimelineService { @GET @Path("/{username}") public String getUpdates(@PathParam("username") String u) { ... } }

M apping a path parameter

Name defined in path expression; segment injected into method

slide-28
SLIDE 28

@Path("/timeline") public class TimelineService { @GET @Path("/{id:[0-9]+}") public String getUpdatesById(@PathParam("id") long id) { ... } @GET @Path("/{username}") public String getUpdatesByUsername( @PathParam("username") String u) { ... } } @Path("/timeline") public class TimelineService { @GET @Path("/{id:[0-9]+}") public String getUpdatesById(@PathParam("id") long id) { ... } @GET @Path("/{username}") public String getUpdatesByUsername( @PathParam("username") String u) { ... } }

M apping different patterns

Fallback if patterns don't match

slide-29
SLIDE 29

N eg otiating a res pons e

Whic h repres entation?

– Plain text? – HTML? – XML? – JSON?

The c lient needs to tell us

– Accept formats, weighted by preference

We have to dec ide w hat w e s upport

– Respond with best match

slide-30
SLIDE 30

@Path("/timeline") public class TimelineService { @GET @Path("/{u}") @Produces("applic ation/xml") public String getUpdatesAs X ml(@PathParam("u") String u) { ... } ... } @Path("/timeline") public class TimelineService { @GET @Path("/{u}") @Produces("applic ation/xml") public String getUpdatesAs X ml(@PathParam("u") String u) { ... } ... }

Produc ing explic itly

Specify which formats are supported using @Produces

slide-31
SLIDE 31

@Path("/timeline") public class TimelineService { @GET @Path("/{u}") @Produces("applic ation/js on") public String getUpdatesAs Js on(@PathParam("u") String u) { ... } ... } @Path("/timeline") public class TimelineService { @GET @Path("/{u}") @Produces("applic ation/js on") public String getUpdatesAs Js on(@PathParam("u") String u) { ... } ... }

Produc ing explic itly

Specify which formats are supported using @Produces

slide-32
SLIDE 32

S implifying res pons e produc tion

C reating X M L and JS ON is laborious :( JAX -R S s upports c onverters

– HTTP entity body readers/writers

Provides built-in JAX B provider!

– Object ⇔ XML – Object ⇔ JSON

slide-33
SLIDE 33

@XmlRootElement(name = "updates") public class Timeline implements Serializable { private List<Update> updates = new ArrayList<Update>(); // constructors @XmlElement(name = "update") public List<Update> getUpdates() { return updates; } public void setUpdates(List<Update> updates) { this.updates = updates; } } @XmlRootElement(name = "updates") public class Timeline implements Serializable { private List<Update> updates = new ArrayList<Update>(); // constructors @XmlElement(name = "update") public List<Update> getUpdates() { return updates; } public void setUpdates(List<Update> updates) { this.updates = updates; } }

A model w ith X M L hints

slide-34
SLIDE 34

@Entity @XmlRootElement public class Update implements Serializable { private Long id; private User user; private Date created; private String text; // getters and setters } @Entity @XmlRootElement public class Update implements Serializable { private Long id; private User user; private Date created; private String text; // getters and setters }

A related model w ith X M L hints

slide-35
SLIDE 35

@Path("/timeline") public class TimelineService { @GET @Path("/{u}") @Produces("application/xml") public Timeline getUpdates(@PathParam("u") String u) { List<Update> updates = ...; return new Timeline(updates); } } @Path("/timeline") public class TimelineService { @GET @Path("/{u}") @Produces("application/xml") public Timeline getUpdates(@PathParam("u") String u) { List<Update> updates = ...; return new Timeline(updates); } }

Turning produc tion over to JAX B

slide-36
SLIDE 36

R E S TE as y

Fully c ertified JAX -R S implementation Portable to any c ontainer E mbedded s erver for tes ting C lient-s ide framew ork for JAX -R S R es pons e c ac hing and c ompres s ion R ic h s et of providers

– XML, JSON, RSS, Atom, YAML, etc.

As ync hronous s upport

slide-37
SLIDE 37

public interface TimelineClient { @GET @Path("/timeline") @Produces("application/xml") Timeline getUpdates(@QueryParam("count") int count); } public interface TimelineClient { @GET @Path("/timeline") @Produces("application/xml") Timeline getUpdates(@QueryParam("count") int count); }

Invoking a s ervic e w ith R E S TE as y

TimelineClient client = ProxyFactory.create(TimelineClient.class, ROOT_URI); String response = client.getUpdates(25); TimelineClient client = ProxyFactory.create(TimelineClient.class, ROOT_URI); String response = client.getUpdates(25);

slide-38
SLIDE 38

What does S eam 2 provide?

R E S TE as y boots trap and c onfig uration

– Automatic resource/provider discovery – Resources/providers are Seam components

S eam s ec urity

– HTTP authentication – Authorization: @Restrict, @PermissionCheck

E xc eption to HTTP res pons e mapping M edia type extens ion mapping R E S T C R U D framew ork

slide-39
SLIDE 39

public abstract class Application { public abstract Set<Class<?>> getClasses(); public abstract Set<Object>getSingletons(); } public SocializeConfig extends Application { ... } <context-param> <param-name>javax.ws.rs.core.Application</param-name> <param-value>com.socialize.SocializeConfig</param-value> </context-param> public abstract class Application { public abstract Set<Class<?>> getClasses(); public abstract Set<Object>getSingletons(); } public SocializeConfig extends Application { ... } <context-param> <param-name>javax.ws.rs.core.Application</param-name> <param-value>com.socialize.SocializeConfig</param-value> </context-param>

Typic al JAX -R S s etup (Java E E 5)

slide-40
SLIDE 40

R E S T as a S eam res ourc e

http://socialize.com/seam/resources/rest/timeline/mojavelinux http://socialize.com/seam/resources/rest/timeline/mojavelinux

slide-41
SLIDE 41

@Name("timelineService") @Path("/timeline") public class TimelineService { @In TimelineDao timelineDao; @GET @Path("/{u}") @Produces("application/xml") public Timeline getUpdates(@PathParam("u") String u) { return timelineDao.fetchTimelineForUsername(u); } } @Name("timelineService") @Path("/timeline") public class TimelineService { @In TimelineDao timelineDao; @GET @Path("/{u}") @Produces("application/xml") public Timeline getUpdates(@PathParam("u") String u) { return timelineDao.fetchTimelineForUsername(u); } }

S eam-infus ed R E S T

slide-42
SLIDE 42

<exception class="com.socialize.NoSuchUserException"> <http-error error-code="404"> <message>No such user</message> </http-error> </exception> <exception class="com.socialize.NoSuchUserException"> <http-error error-code="404"> <message>No such user</message> </http-error> </exception>

Trapping exc eptions

slide-43
SLIDE 43

R E S T in a few frag ments

<components> <framework:entity-home name="userHome" entity-class="com.socialize.model.User"/> <resteasy:resource-home name="userResourceHome" path="/users" entity-home="#{userHome}" entity-id-class="java.lang.Long" media-types="application/xml application/json" readonly="false"/> <resteasy:resource-query name="userResourceQuery" path="/users" entity-class="com.socialize.model.User" media-types="application/xml application/json"/> </components> <components> <framework:entity-home name="userHome" entity-class="com.socialize.model.User"/> <resteasy:resource-home name="userResourceHome" path="/users" entity-home="#{userHome}" entity-id-class="java.lang.Long" media-types="application/xml application/json" readonly="false"/> <resteasy:resource-query name="userResourceQuery" path="/users" entity-class="com.socialize.model.User" media-types="application/xml application/json"/> </components>

slide-44
SLIDE 44

Java E E 6, keeping it s imple

@ApplicationPath("rest") public class JaxRsConfig extends Application {} @ApplicationPath("rest") public class JaxRsConfig extends Application {} @Stateless @Path("/timeline") public class TimelineService { @PersistenceContext EntityManager em; @GET @Path("/{u}") @Produces("application/xml") public Timeline getUpdates(@PathParam("u") String u) { return new Timeline(em.createQuery( "select u from Update u where u.user.username = :u") .setParameter("u", u).getResultList()); } } @Stateless @Path("/timeline") public class TimelineService { @PersistenceContext EntityManager em; @GET @Path("/{u}") @Produces("application/xml") public Timeline getUpdates(@PathParam("u") String u) { return new Timeline(em.createQuery( "select u from Update u where u.user.username = :u") .setParameter("u", u).getResultList()); } }

Must be a managed bean to enable CDI

slide-45
SLIDE 45

Java E E 6, keeping it c lean

@ApplicationPath("rest") public class JaxRsConfig extends Application {} @ApplicationPath("rest") public class JaxRsConfig extends Application {} @Stateless @Path("/timeline") public class TimelineService { @Inject TimelineDao timelineDao; @GET @Path("/{u}") @Produces("application/xml") public Timeline getUpdates(@PathParam("u") String u) { return timelineDao.fetchTimelineForUsername(u); } } @Stateless @Path("/timeline") public class TimelineService { @Inject TimelineDao timelineDao; @GET @Path("/{u}") @Produces("application/xml") public Timeline getUpdates(@PathParam("u") String u) { return timelineDao.fetchTimelineForUsername(u); } }

slide-46
SLIDE 46

S oc ialize demo

slide-47
SLIDE 47

S ummary and c all to ac tion

R es pec t HTTP

– Resources are the foundation of the web

E xpos e your data in a s tandard w ay

– Don’t ball it up inside web pages!

E mbrac e s implic ity

– Seam 2 + RESTEasy – Java EE 6 (JAX-RS + CDI) – Seam 3 integration coming soon...

slide-48
SLIDE 48

M us t reads

R E S Tful Web S ervic es Richardson & Ruby O’ Reilly R E S Tful Java w ith JAX - R S Bill Burke O’ Reilly

slide-49
SLIDE 49

To follow me

mojavelinux

slide-50
SLIDE 50

G E T /ques tions ? HTTP/1.1

slide-51
SLIDE 51

Pres entation res ourc es

JS R -311

– http://jcp.org/en/jsr/detail?id=311

R E S TE as y

– http://jboss.org/resteasy

S eam R E S TE as y integ ration

– Web Services chapter of Seam reference guide

B ill B urke’s R E S T s eries on DZ one

– http://java.dzone.com/articles/putting-java-rest

C ode s amples

– http://seaminaction.googlecode.com/svn/demos