View
13.736
Download
8
Category
Preview:
DESCRIPTION
Building Flexible APIs for Web 2.x/Cloud Applicationssession 25208, JavaOne 2011
Citation preview
¡ Raymond Feng § Staff Software Engineer – Shutterfly, Inc. § Member – Apache Software Foundation § Committer: Apache Tuscany, Wink, Nuvem § Co-‐author – Tuscany SCA In Action
¡ Luciano Resende § Staff Software Engineer – Shutterfly, Inc. § Member – Apache Software Foundation § Committer: Apache Tuscany, Wink, Nuvem, PhotoArk
¡ Why open and simple APIs ¡ Sample scenario ¡ Service design ¡ Model data using DSL ¡ Define the service interface ¡ Bind to REST and JSONRPC ¡ Implement, deploy and test ¡ Documentation ¡ Q&A
¡ A great way to build the ecosystem ¡ For some companies, APIs = products ¡ Proliferation of mobile clients ¡ Universal access for internal systems/web or mobile fronts/third party apps
Top APIs for Mashups
¡ Address Book Service § Provide “web scale” contact management functionality
§ Consumers ▪ Access from internal applications running within the same data center ▪ Java, .NET
▪ Access from browsers ▪ Access from mobile applications ▪ Access from newly acquired company ▪ Access from 3rd party applications
Coarse-‐grained Fine-‐grained
Remotable interface (Possible to deploy service providers and consumers to two different JVMs that communicate using a protocol stack)
Local interface (Must be in the same class loading space within the same JVM)
Data by value in documents (Share the same info set)
Data by reference in Java programming (share the same object instances)
Data in documents (hierarchical structures such as XML or JSON, ids or links are required to reference data outside the document)
Data in OO graphs (for example, circular references are allowed)
Stateless Various scopes (stateless or stateful)
¡ Stateless is key for service scalability § Services are designed to be scalable and ready for deployment into high-‐availability infrastructures. To accomplish this they should not rely on long-‐lived relationships between consumer and provider, nor should an operation invocation implicitly rely on a previous invocation.
¡ Loose Coupling is the key for coarse-‐grained services § Interface and implementation § Service providers and consumers § Protocol bindings § Data representations
¡ Data (what info to flow between services) ¡ Interface (operations defined as the data exchange patterns)
¡ Component/Service/Reference (abstraction of business logic unit: functions it provides and functions it consumes)
¡ Implementation (how to write the business logic)
¡ Communication (access protocols) ¡ Composition (wiring services together) ¡ QoS (cross-‐cutting concerns)
• Use Data Transfer Objects (DTO) for remotable coarse-‐grained services § Be marshal-‐able over the network using platform/language independent encodings such as XML, JSON, or other binary ones
§ Be document/resource (hierarchical structure) oriented rather than object-‐oriented
§ Be self-‐contained (using links or ids to reference other data outside the document)
• Use JAXB as canonical DTO representation for POJO. § If possible, generate JAXB classes from XSD § Or write “pure” Java Beans and add JAXB Annotations if necessary
• Don’t mix business logic into the data objects • Do not use interfaces for the data model (interfaces are not friendly data
representations for many Java data bindings such as JAXB and JSON) § Upon de-‐serialization, most frameworks use the default no-‐arg constructor to
instantiate the DTO • Object-‐oriented graph is not remoting friendly
§ The relations between objects need to be maintained by IDs or links instead of programming language specific references/pointers
§ Distributed object model (such as RMI or CORBA) doesn’t fit into SOA • Don’t use language specific serializations such as Java Serialization • Don’t use complex Java generics and collections for DTOs • Multiple-‐inheritance complicates the issues • Avoid to use more than one complex type for the parameters. Use
wrapper object if necessary § One parameter for the HTTP entity § XML documents require a root element
• Strictly follow JavaBeans patterns if we need to use POJOs as the DTOs.
October 3, 2011 14
Domain Model
RDB
MongoDB
Entity Entity Entity
DTO
REST Root
Resource
REST Sub-‐
Resource
DTO DTO
REST Sub-‐
Resource
Locate
CRUD
CRUD
CRUD
POJO XSD
JSON Schema
Textual DSL (such as Sculptor)
Protocol Buffer/Thrift
DDL
12
1. Persistence 2. DTO 3. Mapping 4. Introspection 5. Validation 6. MVC/UI
3
metadata
4
Addressbook.uddl
Java code
Configuration files
Documents (UML diagrams, HTML
docs)
Generated artifacts
Code generation templates
• We adopted Tuscany SCA, which separates componentization, composition, communication and QoS concerns from the business logic. It becomes obviously natural to abstract the data modeling now (inspired by DDD).
• (Annotated) POJO (JAXB, JPA, Morphia) has too much noises and is abuse-‐prone. We want to enforce the patterns.
• XSD is too complicated and it doesn’t fit all for web 2.0 • We need a simple human (& machine) readable language to describe our
domain model to provide/promote: § Service-‐friendly DTO, Persistence (RDB and NoSQL), Governance, Reuse,
Validation, MVC, Best Practice, Documentation • We call the DSL as Universal Data Definition Language (UDDL).
• Derived from an Apache licensed open source project Sculptor § http://fornax.itemis.de/confluence/display/fornax/Sculptor+%28CSC%29
• Easy to learn, intuitive syntax of the textual DSL, based on the concepts from DDD.
• Textual DSL has a lot of productivity benefits over graphical tools • Quick development round trip, short feedback loop • Generation of complete application from a single model, not only fragments that
are hard to fit in to the overall design • Supports JPA (oracle/mysql/postgresql)/MongoDB/JAXB/Spring/SpringMVC • Great extensibility and customization • Based on Eclipse Xtext/Xtend/Xpand code generation framework • Can be used with text editor or any IDE, but DSL editor with error highlight, code
completion, and outline is provided for Eclipse users • Documentation w/ diagrams for domain model • No runtime magic is built into the tools (generated code can be used without the
tooling)
16
Grammar Language (DSL)
EMF Ecore model
Semantic model
Parse tree model
Grammar model
Eclipse UI Xtext
EMF Ecore model
Xtend/Check
Load/save Parse/validate
Extend/transform/validate
Java code
Configuration files
Documents (UML
diagrams, HTML docs)
Xpand
Eclipse Model Workflow Engine
(MWE)
Generated artifacts
Other DSLs (such as XSD, GPB, Thrift or
Avro)
¡ DSL: < 145 lines including blank ones ¡ Java source code:
§ 13 files § >1,500 lines in total § We get setter/getter/fluent APIs, static field names, equals/hasCode/toString, JAXB/JPA/Morphia annotations
¡ Sculptor: http://fornax.itemis.de/confluence/display/fornax/Sculptor+%28CSC%29
¡ Eclipse Xtext: http://www.eclipse.org/Xtext/
¡ Clean and Flexible Interface § Infrastructure details are abstracted away, and declaratively attached to the services if required
¡ Remote friendly interfaces § Always use remote friendly data objects
¡ Identify required Data Access Patterns
¡ Anti-‐Patterns § Don’t make your service interfaces dependent of protocol specific information (e.g. HTTP Headers, etc)
public interface AddressBookService { PaginatedCollection<Contact> findContacts(String userId, ContactFilterContext filterContext, PageContext pageContext); Contact findContact(String userId, String contactId) throws NotFoundException; void updateContact(String userId, Contact contact) throws NotFoundException; void deleteContact(String userId, String contactId) throws NotFoundException;… }
public interface ContactResource{ @GET @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) PaginatedCollection<Contact> getAll( @QueryParam("startIndex") @DefaultValue("0") int startIndex, @QueryParam("pageSize") @DefaultValue("0") int pageSize, @QueryParam("sort") @DefaultValue("") String sort); @GET @Path("/{id}") @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) Contact get(@PathParam("id") String id); @POST Response create(Contact value); @PUT @Path("/{id}") void update(@PathParam("id") String id, Contact value); @DELETE @Path("/{id}") void delete(@PathParam("id") String id);}
¡ Plain JSON/XML with certain data access patterns mixed in § Simple § No client library is required
¡ Open Data Protocol (OData): § http://www.odata.org/
¡ Google Data Protocol (GData): § http://code.google.com/apis/gdata/
¡ REST has a resource oriented programming model, which does not map gracefully into RPC languages
¡ Use the Resource layer when exposing the service as REST
¡ Use the Service Interface when exposing the services to other RPC style protocols (e.g. JSONRPC, RMI, SOAP WebServices, etc)
Resource Collection
DTO (JAXB)
Browser
Flex Client
DOM
3rd Party App
.NET
JavaScript Object REST w/ JSON
REST w/ XML
SOAP/HTTP JSON-‐RPC
Contacts Id Name …
oAuth Authorization
Other
Security: Authentication
and authorization
Internal Client
DTO (JAXB) High Performance
Binding
Monitoring
Service API
DTO (JAXB)
This provides a RESTful view of the
resources. One Service API might expose multiple resources.
Oracle
MongoDB
¡ Apache Tuscany’s REST binding § http://tuscany.apache.org
¡ Apache Wink JAX-‐RS runtime § http://incubator.apache.org/wink
¡ Start a MongoDB ¡ Start Tuscany with embedded Jetty (within Eclipse)
¡ Start a browser to test REST and JSONRPC
¡ Composition diagram § Describe the service and the assembly
¡ Data Model § Describe data and the relationships
¡ Service Documentation § Describe service interfaces and resources
Component Component
SCA domain
UDDL (xtext/xpand)
UML-‐like diagrams
POJO POJO
POJO
Interface description Interface
description
Enunciate (Javadoc/APT)
Interface (SCA, JAX-‐WS, JAX-‐RS,
etc.)
Tabular view of data
description
¡ Apache Tuscany SCA composite diagram generator § https://svn.apache.org/repos/asf/tuscany/sca-‐java-‐2.x/trunk/maven/tuscany-‐diagram-‐plugin/
¡ Enunciate (Generating documents and client code) § http://enunciate.codehaus.org/
¡ Google API explorer § http://code.google.com/apis/explorer/ § http://code.google.com/p/google-‐apis-‐explorer/
Recommended