Most substantial iPhone applications require some integration with information stored on a server and almost all enterprise iPhone applications require server integration. This brief article describes some of the potential solutions for this integration problem and focuses on cataloging tools to solve the problem using a RESTful approach. Future articles will describe the components in depths; including code samples.
If getting two servers to communicate is like two adults having a conversation then getting a server to communicate with a mobile device, like an iPhone is like an adult having a conversation with a 6 year old child. The child and the adult know a lot of the same words, but the child has a limited vocabulary, listens slower, is easily distracted, and repeats everything it hears to random passing strangers. Therefore, when one architects a system that will include mobile devices one must accommodate these childish behaviors.
In accommodating the mobile devices limited vocabulary, one should not architect a standards stretching SOAP interface that uses all the power of the WS-* standards. The interface specification should be just rich enough to communicate the information necessary; otherwise the code for the device will be overly complicated and brittle. You will also need to plan for multiple versions of the interface to be operational at the same time because you cannot completely control the adoption of updated versions of the application.
One cannot assume that the connection to the device will always be WiFi or even full 3G speed. The device may be in a remote area or in the middle of a packed football stadium. Assume the worst for bandwidth and connection reliability. An additional interesting problem is testing these connection-limited scenarios before the app gets into user's hands.
Additionally, the connection may not be long lived and the amount of data transmitted should be small enough to be easily digested so that the device can receive it and act on it before it gets distracted.
Once you tell the phone something, you cannot be guaranteed that the information stays on the phone. Unlike browsers, that only store small bits of user data, the phone can store enough information to be a gold mine to an identity thief. Additionally, the transmission of the data will be over publically accessible wireless networks. Therefore, the architecture must account for the openness of the lower transport layers of the communications and of the fact that certain data on the device must be tightly controlled.
There are several potential solutions for connecting mobile devices, like the iPhone, to enterprise servers.
- REST – A REST solution uses HTTP to communicate simple URI based queries to a server, which responds with a structured reply, usually XML or JSON. REST services use the full bouquet of HTTP operations, GET, POST, PUT, and DELETE to communicate the nature of the operation, and either path parameters or query parameters to provide variables for the operations. Writing REST clients takes the simplicity of making HTTP requests and combines it the control of communicating strongly structured data. REST services can easily return binary data, such as images, without having to wrap them in transport specific encoding (like Base64) because the client is communicating with a simple HTTP server that can as easily return PNG data as XML data. As you can probably guess from the title, this article and future articles will focus on a REST approach to interfacing with enterprise systems from an iPhone.
- SOAP – SOAP can appear to be a natural choice since many enterprises have ample supply of SOAP services and SOAP knowledgeable developers. SOAP does carry significant overhead in complexity that may make interfacing with it on the iPhone very difficult and time consuming, in my opinion there are no simple SOAP queries. When using SOAP on a device that doesn't have native SOAP support one may get the communications efficiency of XML with the developer efficiency of a custom developed protocol.
- Custom developed high-level protocol – This may be an appropriate solution if bandwidth and efficiency are of utmost concern and developer time is a lesser concern. This applies if the majority of the data being transported is binary streams such as audio or video streams.
- HTML Scraping – HTML Scraping is the reuse of existing web pages and forms by the iPhone app. The app programmatically retrieves the pages, scrapes information and represents in a thick client format. While this approach can eliminate server side program changes it introduces a large risk of failure down the road when the server side eventually changes.
- Hybrid Solutions – In many situations a hybrid solution where one channel of communications uses REST or SOAP while another channel uses a custom developed protocol. An example of this is a chat program that uses REST to communicate presence and roster information, but uses a custom binary protocol to transport voice and video data.
To implement a RESTful system one needs to have components in both the service tier and the client tier that understand the REST protocol. This section introduces examples of those components, which are illustrated in the following diagram.
On the JavaEE side, REST services are usually configured within a WAR project similarly to a JSP or Struts. The REST servlet can co-exist in the WAR project with other servlet technologies such as JSPs and Java based servlets. The REST servlet may have access control applied to it using standard JAAS configuration within web.xml, but it may also implement it's own security mechanisms.
In the structure shown in the diagram, the REST resources are the Java classes that implement the REST endpoints specific to your application. These resources declare the endpoint specifications; including URL path, path parameters, query parameters.
There are several packages that implement REST services within a JavaEE container. Many of them support the JAX-RS (or JSR-311) specification. Using a JAX-RS complaint REST package is not required, but it is recommended so that if the chosen REST service implementation is not satisfactory for some reason it may be swapped out for a more suitable package without re-implementing the REST resources. All of the JSR-311 packages listed below can run inside or outside of a JaveEE container.
There are several JAX-RS compliant packages available including:
- CXF ( http://cxf.apache.org/) is the grand daddy Java web service package that is a merging of two older web service projects, XFire and Celtix. Recent versions of the package have support for JAX-RS web services. In my evaluation of CXF for a client the documentation and implementation of JAX-RS within CXF left me feeling that REST support was an afterthought. If all you need is REST support from a package, CXF is probably overkill.
- Jersey ( https://jersey.dev.java.net/) is the reference implementation of JSR-311. It is lightweight and completely focused on REST services. It comes bundled with Jetty if you wish to deploy a REST services outside of a JavaEE or Tomcat container. It has an optional component for Spring integration wherein the REST resource is declared in a Spring configuration file so that Spring controlled resources are injected into the REST resource.
- RESTeasy ( http://jboss.org/resteasy) is a JBoss project to implement JSR-311 and is well integrated with the JBoss AS 5.x. It is also available as a separate download so it can be integrated with other containers.
- Restlet ( http://www.restlet.org) is a project that predates the JSR-311 specification and has moved to provide a standards compliant interface over it's existing framework. Restlet focuses on a clean and lean REST implementation.
- Another significant REST service package that is not JAX-RS complaint is Spring 3.0 ( http://www.springframework.org). If your infrastructure already depends on Spring this may be a good alternative. Another up-and-coming framework, Seam ( http://seamframework.org), has JSR-311 support scheduled for version 3.0.
To support the JSR-311 resources used to implement the endpoints, additional packages, like JAXB or XStream, are useful to expedite the marshalling and unmashalling of objects from the HTTP transport to Java.
The iPhone OS includes components that support network interactions using the HTTP protocol and components to perform stream XML parsing. Combining these two component sets one can easily construct REST clients. The primary component for HTTP communications is NSURLConnection, and the primary component for XML parsing is NSXMLParser.
NSURLConnection – This object provides functionality to synchronously or asynchronously perform HTTP requests. The synchronous functionality is simplest to use, but is inappropriate if the connection may require authentication or may return large datasets. The asynchronous mode of operation is more complicated to use, but does support callbacks for authentication and large datasets. Both modes are tightly integrated with the iPhone OS, which is helpful for managing certificates and cookies. Any cookie that is stored on the phone for a particular site will be automatically included in requests sent by the connection. This reduces most of heavy lifting when dealing with session cookies. One must still explicitly store returned cookies into the OS's cookie jar.
One should carefully plan how they mix asynchronous and synchronous methods. In my experience it is best to use all of just one technique to keep the code consistent in its behavior. Also, there are potentially unexpected side effects of using the asynchronous methods from within threads other than the main thread of the application.
NSXMLParser – This object is a stream XML parser similar to the Java SAX parser. Once fed data, the parser calls a delegate class on the beginning and end of each element and for string contents. NSXMLParser can parse data from URLs, filepaths, or in-memory data. This object can be used to get contents directly from a web service, but it lacks the ability to use any HTTP methods other than GET and cannot respond to authentication queries from the server, so the application must already be authenticated with the server before retrieving data using NSXMLParser.
There are no JAXB/XMLBeans corollaries in iPhone OS, so one is left to hand coding serialization and deserialization methods to map between Core Data managed entities and XML.
Future articles will address more specifics of these components when used in an iPhone application interfacing with a RESTful service.