Transcript of "Building Flexible APIs for Web 2.x/Cloud Applications (JavaOne 2011 Session 25208)"
Raymond Feng (email@example.com) Luciano Resende (firstname.lastname@example.org)
¡ Raymond Feng § Staﬀ Software Engineer – Shutterﬂy, Inc. § Member – Apache Software Foundation § Committer: Apache Tuscany, Wink, Nuvem § Co-‐author – Tuscany SCA In Action ¡ Luciano Resende § Staﬀ Software Engineer – Shutterﬂy, Inc. § Member – Apache Software Foundation § Committer: Apache Tuscany, Wink, Nuvem, PhotoArk
¡ Why open and simple APIs ¡ Sample scenario ¡ Service design ¡ Model data using DSL ¡ Deﬁne 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 Local interface (Possible to deploy service providers and (Must be in the same class loading space consumers to two diﬀerent JVMs that within the same JVM) communicate using a protocol stack) Data by value in documents Data by reference in Java programming (Share the same info set) (share the same object instances) Data in documents (hierarchical Data in OO graphs (for example, circular structures such as XML or JSON, ids or references are allowed) links are required to reference data outside the document) 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 ﬂow between services) ¡ Interface (operations deﬁned 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 speciﬁc references/pointers § Distributed object model (such as RMI or CORBA) doesn’t ﬁt into SOA • Don’t use language speciﬁc 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.
• 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 ﬁt 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 Deﬁnition Language (UDDL).
• Derived from an Apache licensed open source project Sculptor § http://fornax.itemis.de/conﬂuence/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 beneﬁts 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 ﬁt 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
Semantic model Generated artifacts Grammar Language Eclipse Model Load/save (DSL) Workﬂow Engine Java code (MWE) Parse/validate Eclipse Xtext UI Conﬁguration ﬁles Xpand Documents Parse tree Grammar model model (UML diagrams, HTML docs) EMF Ecore model Xtend/ Check EMF Ecore model Other DSLs (such as XSD, GPB, Thrift or Extend/ Avro) transform/ validate
¡ DSL: < 145 lines including blank ones ¡ Java source code: § 13 ﬁles § >1,500 lines in total § We get setter/getter/ﬂuent APIs, static ﬁeld names, equals/hasCode/toString, JAXB/JPA/ Morphia annotations
¡ 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 speciﬁc information (e.g. HTTP Headers, etc)
¡ 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)
This provides a JavaScrip RESTful view of the t Object resources. One Service Monitoring REST w/ JSON API might expose multiple resources. Browser Contacts Id Name … DTO Mongo (JAXB) DB DOM Flex REST w/ XML Resource Client Collection Oracle .NET Service 3rd Party API SOAP/HTTP App JSON-‐RPC DTO (JAXB) Other Internal DTO Client (JAXB) High Performance Security: Binding Authentication oAuth and Authorization authorization