Practical RESTful Persistence

45
@shaunMsmith #DV13 #JPARS Practical RESTful Persistence with EclipseLink JPA-RS Shaun Smith Oracle

description

Java EE developers are increasingly required to embrace thin-server-architecture client application development while leveraging their existing components. On the surface, this appears to simply mean using JAX-RS to expose RESTful services. But the real challenges are often misunderstood and underestimated. EclipseLink has solved a large part of this problem through its new JPA-RS feature which integrates JAX-RS, JAXB and JPA to allow developers to expose their persistent entities over REST with support for all lifecycle operations and query execution. In building JPA-RS, EclipseLink faced and overcame many of the challenges developers face when realizing a REST resource model, addressing HATEOS, and the infrastructure for JSON and XML binding.

Transcript of Practical RESTful Persistence

Page 1: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Practical RESTful Persistencewith EclipseLink JPA-RS

Shaun SmithOracle

Page 2: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

• JPA 2.0 (EE 6) and 2.1 (EE 7) reference implementation

• JPA provider in GlassFish and Oracle WebLogic

• Project founded on mature Oracle TopLink codebase

• EPL and EDL licensed open source JPA and JAXB implementation

Page 3: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Browser

Database

Page 4: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

DatabaseDatabase

Java

Browser

Page 5: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

DatabaseDatabase

Java

EclipseLink JPA

Browser

Page 6: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Database

JAX-RS

Database

Java

Browser

EclipseLink JPA

Page 7: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Database

JAX-RS

Database

Java

Browser

EclipseLink JPA

EclipseLink JAXB / JSON Binding

Page 8: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Database

JAX-RS

Database

Java

Browser

EclipseLink JPA

EclipseLink MOXy

Page 9: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Database

JAX-RS

Database

Java

Browser

EclipseLink JPA

EclipseLink MOXy

Page 10: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

EclipseLink JPA

Database

Java

EclipseLink MOXy

BrowserHTML5

Browser

JAX-RS

Page 11: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Java

Browser

JAX-RS

EclipseLink MOXy

EclipseLink JPA

Database

{ id: 5, …}

Page 12: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Browser

JAX-RS

EclipseLink MOXy

Java

EclipseLink JPA

Database

{ id: 5, …}

Page 13: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Browser

JAX-RS

EclipseLink MOXy

Java

EclipseLink JPA

Database

Page 14: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Database

JAX-RS

Database

Java

Browser

EclipseLink JPA

EclipseLink MOXy

Page 15: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Binding PersistenceXML / JSON

Java PersistenceRelational / NoSQL

JAX-RS

EclipseLink MOXy

EclipseLink JPA

Database

Java

Browser

Page 16: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Binding PersistenceXML / JSON

Java PersistenceRelational / NoSQL

JAX-RS

EclipseLink MOXy

EclipseLink JPA

Database

Java

Browser

Page 17: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

EclipseLink MOXyEclipseLink MOXy

• JAXB for Java/XML binding—covert Java to/from XML

• Java/JSON binding—convert Java to/from JSON

• Currently no Java/JSON binding standard• Java API for JSON Processing (JSR 535) is parsing, not

binding

• EclipseLink interprets JAXB XML bindings for JSON• Content-type selectable by setting property on

Marshaller/Unmarshaller

Page 18: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

XML and JSON from JAXB MappingsXML and JSON from JAXB Mappings

{ "phone-numbers" : [ { "id" : 2, "num" : "512-555-9999", "type" : "mobile" } ], "address" : { "city" : "New York", "id" : 1, "street" : "Central Park East" }, "firstName" : "Woody", "id" : 1, "lastName" : “Allen"}

<?xml version="1.0" encoding="UTF-8"?><customer> <phone-numbers> <phone-number> <id>2</id> <num>512-555-1234</num> <type>home</type> </phone-number> </phone-numbers> <address> <city>New York</city> <id>1</id> <street>Central Park East</street> </address> <firstName>Bill</firstName> <id>1</id> <lastName>Allen</lastName></customer>

Page 19: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Challenges – Binding JPA Entities to XML/JSONChallenges – Binding JPA Entities to XML/JSON

• Composite Keys/Embedded Key Classes

• Byte Code Weaving

• Bidirectional/Cyclical Relationships

<customer> <phone-numbers> <phone-number> <id>1</id> ... <type>mobile</type> </phone-number></phone-numbers></customer>

JPAJAXB

Page 20: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Bidirectional RelationshipBidirectional Relationship@Entitypublic class Customer{

...@OneToMany(mappedBy="owner")private List<Phone> phones;

}

@Entitypublic class Phone{

...@ManyToOneprivate Customer owner;

}

Page 21: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

What about @XmlTransient?What about @XmlTransient?@Entitypublic class Customer{

...@OneToMany(mappedBy=“owner")private List<Phone> phones;

}

@Entitypublic class Phone{

...@ManyToOne@XmlTransientprivate Customer owner;

}

Page 22: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

With @XmlTransientWith @XmlTransient

Loses the relationship! <customer> <phone-numbers> <phone-number> <id>1</id> ... <type>mobile</type> </phone-number></phone-numbers></customer>

MarshallMarshall

Customer

Phone

UnmarshallUnmarshall

X

Customer

Phone

owner

phones phones

Page 23: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

EclipseLink XmlInverseReferenceEclipseLink XmlInverseReference@Entitypublic class Customer{

...@OneToMany(mappedBy=“owner")private List<Phone> phones;

}

@Entitypublic class Phone{

...@ManyToOne@XmlInverseReference(mappedBy=“phones")private Customer owner;

}

Page 24: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

With @XmlInverseReferenceWith @XmlInverseReference

EclipseLink restores relationships on unmarshall!<customer> <phone-numbers> <phone-number> <id>1</id> ... <type>mobile</type> </phone-number></phone-numbers></customer>

MarshallMarshall

Customer

Phone

UnmarshallUnmarshall

Customer

Phone

owner

phones phones

owner

Page 25: Practical RESTful Persistence

Demo

@shaunMsmith#DV13 #JPARS

Page 26: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Binding PersistenceXML / JSON

Java PersistenceRelational / NoSQL

EclipseLink MOXy

EclipseLink JPA

Database

Java

Browser

JAX-RSJAX-RS

Page 27: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

JAX-RS with JPA ExampleJAX-RS with JPA Example

public class InvoiceService {...

public Invoice read(int id) {

return null;

}

...

Page 28: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

JAX-RS with JPA ExampleJAX-RS with JPA Example

@Stateless

public class InvoiceService {...

public Invoice read(int id) {

return entityManager.find(Invoice.class, id);

}

...

Page 29: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

JAX-RS with JPA ExampleJAX-RS with JPA Example@Path("/invoice")

@Stateless

public class InvoiceService {...

public Invoice read(int id) {

return entityManager.find(Invoice.class, id);

}

... http://[machine]:[port]/[web-context]/invoice http://[machine]:[port]/[web-context]/invoice

Page 30: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

JAX-RS with JPA ExampleJAX-RS with JPA Example@Path("/invoice")

@Stateless

public class InvoiceService {...

@Path("{id}”)

public Invoice read(@PathParam("id") int id) {

return entityManager.find(Invoice.class, id);

}

... http://[machine]:[port]/[web-context]/invoice/4 http://[machine]:[port]/[web-context]/invoice/4

Page 31: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

JAX-RS with JPA ExampleJAX-RS with JPA Example@Path("/invoice")

@Stateless

public class InvoiceService {...

@GET

@Path("{id}”)

public Invoice read(int id) {

return entityManager.find(Invoice.class, id);

}

... GET http://[machine]:[port]/[web-context]/invoice/4GET http://[machine]:[port]/[web-context]/invoice/4

Page 32: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

JAX-RS with JPA ExampleJAX-RS with JPA Example@Path("/invoice")

@Stateless

public class InvoiceService {...

@Produces({"application/xml"})

@GET

@Path("{id}")

public Invoice read(@PathParam("id") int id) {

return entityManager.find(Invoice.class, id);

}

... GET http://[machine]:[port]/[web-context]/invoice/4GET http://[machine]:[port]/[web-context]/invoice/4

Page 33: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Invoice Bean

JAX-RSJAX-RS

JAX-RS with JPAJAX-RS with JPA GET http://.../invoice/4GET http://.../invoice/4

http://.../invoice/4 mapped to beanhttp://.../invoice/4 mapped to bean

JPA

Accounting PUBean uses JPABean uses JPA

GETGET

GET http://.../invoice/4 mapped to methodGET http://.../invoice/4 mapped to methodContract Bean Payment Bean

...GETGETGETGETGETGET GETGETGETGETGETGETGETGETGETGETGETGET

Page 34: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

JAX-RS

EclipseLink MOXy

EclipseLink JPA

Java

JPA-RSJPA-RS

JAX-RS

EclipseLink MOXy

EclipseLink JPA

Java

Browser

Database

Page 35: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

EclipseLink JPA-RSEclipseLink JPA-RS

• Automatically provides REST operations for entities in persistence unit (GET, PUT, POST, DELETE)

• Automatic generation of XML and JSON bindings• Leverages EclipseLink’s JAXB/JPA fidelity features to

avoid lossy transformations

• Automatic publication of REST API metadata

Page 36: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

EclipseLink JPA-RSEclipseLink JPA-RS

• Supports invocation of named queries via HTTP

• Server side caching—EclipseLink clustered cache

• Automatic injection of links for entity relationships• Default Resource Model generation

Page 37: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Browser

Java

Database

11 22

{ "id": 1, "lastName": "Smith", … "address": { "_link": { "href": "http:/…/Address/2", "method": "GET", "rel": "self" } }

{ "id": 2, "city": ”Toronto", …}

...

...

Page 38: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Configuring JPA-RSConfiguring JPA-RS

• Add JPA-RS web fragment jar to WEB-INF/lib!

Page 39: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

JPA

JPA-RS

JAX-RSJAX-RS

JPA-RSJPA-RS

Accounting

GET http://.../persistence/Accounting/Invoice/4GET http://.../persistence/Accounting/Invoice/4

JPA-RS maps URI http://.../persistence/Accounting/Invoice/4 to Accounting PU and Invoice entity

JPA-RS maps URI http://.../persistence/Accounting/Invoice/4 to Accounting PU and Invoice entity

JAX-RS http://.../persistence/Accounting/Invoice/4mapped to JPA-RS serviceJAX-RS http://.../persistence/Accounting/Invoice/4mapped to JPA-RS service

Human Resources

Benefits

...

Page 40: Practical RESTful Persistence

Demo

@shaunMsmith#DV13 #JPARS

Page 41: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Demo ModelDemo Model

Page 42: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

EclipseLink JPA-RS RoadmapEclipseLink JPA-RS Roadmap

• Resource Model• Scope of resource• Entity format• partial entities/projections

• Configuration• URL mapping/customization• Manage Entity exposure

• Meta-data• JSON Schema? Swagger? ...

Page 43: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

Browser

JAX-RS

EclipseLink MOXy

Java

EclipseLink JPA

Database

Page 44: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

SummarySummary

• Java EE stack has (most of) what you need to build Thin Server Architecture applications

• You have to be aware of various impedance mismatches

• EclipseLink JPA-RS • Integrates JAX-RS / JAXB / JPA• Eliminates JAX-RS boilerplate for data access• Simplifies Java EE Thin Server Architecture applications

☛ www.eclipse.org/eclipselink

Page 45: Practical RESTful Persistence

@shaunMsmith#DV13 #JPARS

The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.