REST API design and construction with Java EE - pages from my work diary


Published on

When developers use JPA, Bean Validation and other features with JAX-RS, they start off with only a faint indication of the problems they would run into. There is more than one way to use these in conjunction with each other. Some are good, some are okay, and some are downright awful. This talk will explore practical solutions and patterns for REST APIs built with Java EE. Attendees will learn of contextual rules so they're more effective at constructing and designing JAX-RS based REST APIs.

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

REST API design and construction with Java EE - pages from my work diary

  1. 1. REST API DESIGN AND CONSTRUCTION WITH JAVA EE PAGES FROM MY WORK DIARY By Vineet Reynolds L P / @VineetReynolds Senior Software Engineer JBoss Developer Experience, Red Hat
  2. 2. ABOUT THE SPEAKER Engineer in the JBoss Developer Experience team Currently, contributor to : JBoss Forge 1.x and 2.0 AngularJS scaffolding for JBoss Forge JDF quickstarts TicketMonster Others: Arquillian (GlassFish, WebLogic container adapters)
  3. 3. AGENDA A 10 minute guide to REST JPA and JAX­RS Writing a data­driven REST API with JPA and JAX­RS Composite keys Cyclic and bi­directional relationships Lazy­fetching Class hierarchies (java.sql.Date) Bean Validation and error reporting
  4. 4. A 10 MINUTE GUIDE TO REST Note ­ this is really a 10 minute guide. This is not a deep­dive into Roy Fielding's doctoral dissertation.
  5. 5. WHAT IS REST ? REST = REpresentational State Transfer It is an architectural style. It describes the design of a hypermedia system (the web). It intends to conceptualize how a well designed Web application should behave.
  6. 6. EXAMPLES GT/vns E   e e t  returns all Events. GT/vns1 E   e e t /  returns the Event with ID 1. P S   e e t  creates a new Event. OT/vns PT/vns1 U   e e t /  updates the Event. D L T   e e t /  deletes the Event. EEE/vns1
  7. 7. EXAMPLES Assuming G T / v n s 1 E   e e t /  returns                                   {   "ae  JDO"   nm":"UCN,   "esos     ssin":[           {"ae  Arga"}            nm":"eoer ,           {"ae  Ifnsa"}            nm":"niipn ,           {"ae  OeSit ,            nm":"pnhf"}           {"ae  WlFy             nm":"idl"}                   ] }                               What kind of updates can be made in a PUT ? Session names could be updated. New Sessions could be added. Existing sessions could be deleted.
  8. 8. JAX-RS + JPA + EJB : THE BASICS Let's expose a JPA entity as a REST resource.                               @niy Ett pbi ls vn  ulccasEet{   @d   I   @eeaeVlesrtg  eeainyeAT)   Gnrtdau(taey=GnrtoTp.UO   piaeLn d=nl;   rvt ogi  ul   @eso   Vrin   piaeitvrin=0   rvt n eso  ;   @oun   Clm   piaeSrn ae   rvt tignm;   / etr,Stes qas)adhsCd(   /Gtes etr,eul( n ahoe)   ..   . }                           
  9. 9. JAX-RS + JPA + EJB : THE BASICS CREATING NEW EVENTS                               PS sml­vn/eteet TP11 OT/ipeeetrs/vnsHT/. Hs:lclot88 ot oahs:00 CnetTp:apiainjo;hre=T­ otn­ye plcto/sncastUF8 .. . {nm""UCN} "ae:JDO"                                                         HT/. 0 rae TP1121Cetd Lcto:ht:/oahs:00sml­vn/eteet/ oain tp/lclot88/ipeeetrs/vns1 .. .                          
  10. 10. JAX-RS + JPA + EJB : THE BASICS FETCHING ALL EVENTS                               GT/ipeeetrs/vnsHT/. E sml­vn/eteet TP11 Hs:lclot88 ot oahs:00 Acp:apiainjo,tx/li,** cet plcto/sn etpan / .. .                                                         HT/. 0 K TP1120O CnetTp:apiainjo otn­ye plcto/sn .. . ["d:,vrin:,nm""UCN} {i"1"eso"0"ae:JDO"]                          
  11. 11. JAX-RS + JPA + EJB : THE BASICS FETCHING ONE SPECIFIC EVENT                               GT/ipeeetrs/vns1HT/. E sml­vn/eteet/ TP11 Hs:lclot88 ot oahs:00 Acp:apiainjo,tx/li,** cet plcto/sn etpan / .. .                                                         HT/. 0 K TP1120O CnetTp:apiainjo otn­ye plcto/sn .. . {i"1"eso"0"ae:JDO" "d:,vrin:,nm""UCN}                          
  12. 12. JAX-RS + JPA + EJB : THE BASICS UPDATING AN EVENT                               PT/ipeeetrs/vns1HT/. U sml­vn/eteet/ TP11 Hs:lclot88 ot oahs:00 Acp:apiainjo,tx/li,** cet plcto/sn etpan / .. . {i"1"eso"0"ae:JDO ni" "d:,vrin:,nm""UCNIda}                                                         HT/. 0 oCnet TP1124N otn .. .                          
  13. 13. JAX-RS + JPA + EJB : THE BASICS DELETING AN EVENT                               DLT sml­vn/eteet/ TP11 EEE/ipeeetrs/vns1HT/. Hs:lclot88 ot oahs:00 Acp:apiainjo,tx/li,** cet plcto/sn etpan / .. .                                                         HT/. 0 oCnet TP1124N otn .. .                          
  14. 14. COMPOSITE KEYS ARE NOT FUN Addressability suffers. Matrix parameters will help with composite keys.                           / e o vn  ae oain /Kyfreet=nm,lcto GT/vnsnm=UCNlcto=ni E eet;aeJDO;oainIda                       But ... They're not a standard. Just a W3C design note. Lack of client support (but improving). Among popular JS libraries, only Dojo, AngularJS, Backbone.js has support. If cheap, establish a mapping scheme for composite keys.
  15. 15. RELATIONSHIPS Handling modifications to relationships in JPA entities can get difficult.
  16. 16. CREATE A NEW EVENT                               PS bd­vn/eteet TP11 OT/iieetrs/vnsHT/. Hs:lclot88 ot oahs:00 Acp:apiainjo,tx/li,** cet plcto/sn etpan / .. . {nm""UCN,lcto""aglr" "ae:JDO""oain:Bnaoe}                                                         HT/. 0 rae TP1121Cetd Lcto:ht:/oahs:00bd­vn/eteet/ oain tp/lclot88/iieetrs/vns1 .. .                          
  17. 17. FETCH AN EXISTING EVENT                               GT/iieetrs/vns1HT/. E bd­vn/eteet/ TP11 Hs:lclot88 ot oahs:00 Acp:apiainjo,tx/li,** cet plcto/sn etpan / .. .                                                         HT/. 0 K TP1120O CnetTp:apiainjo otn­ye plcto/sn .. . {i"1"eso"0"ae:JDO""oain:Bnaoe,ssin"[} "d:,vrin:,nm""UCN,lcto""aglr""esos:]                          
  18. 18. CREATE A NEW SESSION                               PS bd­vn/etssin TP11 OT/iieetrs/esosHT/. Hs:lclot88 ot oahs:00 Acp:apiainjo,tx/li,** cet plcto/sn etpan / {   "esoNm""eoer,   ssinae:Arga"   "pae""eata"   sekr:Sbsin,   "vn"{i"1   eet:"d:,       "eso"0       vrin:,       "ae:JDO"       nm""UCN,       "oain:Bnaoe,       lcto""aglr"       "esos:]       ssin"[} }                                                         HT/. 0 rae TP1121Cetd Lcto:ht:/oahs:00bd­vn/etssin/ oain tp/lclot88/iieetrs/esos2 .. .                          
  19. 19. FETCH THE NEWLY CREATED SESSION                               GT/iieetrs/esos2HT/. E bd­vn/etssin/ TP11 Hs:lclot88 ot oahs:00 Acp:apiainjo,tx/li,** cet plcto/sn etpan / .. .                                                         HT/. 0 nenlSre ro TP1150Itra evrErr CnetTp:tx/tlcastuf8 otn­ye ethm;hre=t­ JWB005 TPSau 0  r.oeasjcsnmpJoMpigxeto BE006:HT tts50­ogcdhu.ako.a.snapnEcpi fie olzl ntaieacleto frl:cmeapebdeetmd aldt aiyiiilz  olcino oe o.xml.iivn.o n eso truhrfrnecan o.xml.iivn.oe.eso[e oSsin(hog eeec hi:cmeapebdeetmdlSsin"                          
  20. 20. WHAT JUST HAPPENED? E e t s s i n  is lazily fetched. vn.esos During serialization, the proxy does not find an active session. Let's try and solve this crudely, using eager fetching ...                               {i"2"eso"0"esoNm""eoer,sekr:Sbsin,eet: "d:,vrin:,ssinae:Arga""pae""eata""vn" ["d:,vrin:,ssinae:Arga""pae""eata""vn" {i"2"eso"0"esoNm""eoer,sekr:Sbsin,eet ["d:,vrin:,ssinae:Arga""pae""eata""vn" {i"2"eso"0"esoNm""eoer,sekr:Sbsin,eet .. . / hsnvrtriae /Ti ee emnts                          
  21. 21. HOW DO YOU SOLVE THIS ? If you can, do not expose collection members of JPA entities directly. Use sub­resources for dependent collections (1:M). Use a mapping layer. Create Representation classes to map JPA object graphs. The mappings translate RESTful actions into operations in the domain model. Or, use different representations of the same JPA entity for different operations (not a good idea). One to create an entity with collections, another to update only the entity. Model collections as a separate resource. Makes sense for M:N relationships.
  22. 22. JAVA.SQL.* HATES YOU Consider the following                                   @eprlTmoaTp.IE Tmoa(eprlyeTM) jv.tlDt trTm; aaui.aesatie                               During serialization, s a t i e t r T m 's type is j v . q . i e aaslTm. Given a value of 2:00 PM IST, the field will be serialized as {satie:1:00". "trTm""40:0} When deserializing back, { s a t i e : 1 7 ­ 1 "trTm""900­ 0T40:0000:0} 1 1 : 0 0 . 0 + 5 3 "  should be supplied.
  23. 23. JAVA.SQL.* HATES YOU Before, we discuss solutions, let's talk about: ISO8601 vs Unix timestamps. Which one to use ? The former is almost always better. Date, time and timestamp formats. Omit unnecessary info in ISO8601 formats (like time values for Dates).
  24. 24. JAVA.SQL.* HATES YOU Lessons learnt ­ Be aware of the actual types of the objects during serialization and deserialization. Constrain the actual types and hence the serializers/deserializers used. When writing custom serializers, design them for class hierarchies. Think of the equals() contract, but for serialized forms. And of course, avoid java.util.Date/Calendar. Use specific types in Joda­Time and eventually JSR­310 (Java 8). Using a specific type binds a serializer + deserializer to the field.
  25. 25. BEAN VALIDATION AND VIOLATION REPORTING Responses for Constraint violation errors on JPA entities are not standardized. By default, HTML responses will be provided if no E c p i n a p r  exist for xetoMpes CntanVoainxetos osritiltoEcpin. Bean Validation for request parameters is available out­of­ the­box, but requires activation. RESTEasy has one format, Jersey has another.
  26. 26. QUESTIONS ?