The growth of mobile apps has pushed forward the model of creating services that are consumed through APIs to such a degree that APIs are now at the forefront of development. It has become a necessity, not a nice-to-have, to be able to create APIs and serve them at large scales.
Before we look at code examples for creating mobile apps on PaaS, let’s put these new techniques in perspective by briefly examining their evolution.
Before the iPhone first hit the marketplace in 2007, mobile phones had an incredibly tightly controlled environment. It was difficult and often impossible to create third-party mobile applications, and there were strict limitations on what those applications could do. Even the mobile web had its own proprietary formats on early phones. They had their own versions of HTML, like TTML (Tagged Text Markup Language), WML (Wireless Markup Language), and HDML (Handheld Device Markup Language), that were stripped down to the bare minimum and included odd new, arbitrary tags so that they would work on these highly constrained devices.
The iPhone was the first cell phone to ever ship with a fully compatible HTML web browser.
On the original iPhone, third-party apps were originally built as HTML websites optimized for the phone’s screen. Obviously, these were not yet native mobile applications; they were still browser based.
One of the early innovations in mobile application development was writing applications in straight HTML and CSS for phones. This was when we saw a shift in the way that mobile applications were created. At this point, creating a mobile application was still like creating a web application. You still had heavy server-side logic that would create and present all the information, with very little logic residing on the client side.
However, as the iPhone matured, and as Android and Windows Phone devices came to market with native mobile applications, the situation changed dramatically and quickly. Instead of generating HTML and CSS, you created APIs that would be fed into the native mobile client to be processed directly on the phone itself.
The native client might be running on iOS or Android, in an Objective-C or Java environment. These would usually be much heavier in client-side logic, with a lot of the presentation logic and all of the components for the user experience on the client side. Your backend systems therefore had to act and think differently. There would be APIs that fed into these client systems and were consumed by them. This mirrored much of what modern web development was moving toward: thicker client-side logic. On the Web, that meant a lot more JavaScript; in the mobile realm, it meant Objective-C or Java.
In any case, whether the client is a thick web client using JavaScript that consumes APIs or an Objective-C native mobile client, in the end you are going to need data to populate it with. Serving that data is still going to be a problem, no matter what kind of client consumes it. This situation pushed forward a resources-oriented method of creating lightweight JSON and XML services and metaservices to support these mobile applications.
Looking forward, mobile applications will be gaining more and more functionality and speed. Even though modern smartphones are light-years more powerful than even a large computer was 10 years ago, they still have limited capacity and limited bandwidth compared to many desktop computers today. We can expect that phones are going to continue to get faster, cheaper, and smaller with much more functionality, driving even more client-side technology.
Then there’s another important growth factor to consider: we have barely touched the surface of the penetration of the mobile marketplace. Estimates indicate that as of 2012, around 300 to 600 million smartphones were in use. But the ultimate market size of the smartphone era is estimated to be closer to 3 billion smartphones. In 2012, there were only 10% to 15% of the smartphones that will exist in 2022.
So, not only are we going to see apps with enhanced capabilities, but we are going to see a large increase in the number of people consuming these applications.
There is another trend worth noting: the bifurcation of popularity between iOS and Android, and the further splitting of the marketplace by enthusiasts of Windows smartphones and BlackBerry devices. Each of these platforms supports unique ways to build applications. As the smartphone market matures, the differences in technologies are going to become less and less tenable. Developers are going to come up with more creative ways to pack in the functionality, and do so in a way that can be consumed across many platforms at once, taking advantage of the whole mobile market.
Ultimately, there will be an increasing number of people consuming more services, creating higher loads for the backend applications that serve them. So we’ll see the need for backend services and metaservices that are able to move to large scales and do so quickly. They will need to perform well while they gain popularity.
The key takeaway: developers need to think in terms of what it will take to get the backend services for these applications to run well at scale. And that is where PaaS is going to shine.
API-driven development models involve the use of data structures that serialize information into packets that can be distributed between devices. In this section, we’ll review two of them: JSON and XML.
A familiar activity involves taking a structure that has a username and a password, plus a list of friends encapsulating this data; you want to be able to send this data from a server to a client to be consumed by the end user. There are many ways to accomplish tasks like this.
XML is one common method that is prevalent within Java; it’s still a vital tool within many enterprise applications. JSON is a bit newer to the market; it’s a JavaScript representation of objects. JSON’s relationship to JavaScript is key in understanding why this format has taken off.
One of the most common ways that JSON is consumed is through a JavaScript client on the web frontend. Because of that attribute, it is very easy to turn JSON into JavaScript objects through the web client. Since the point of origin of many mobile applications is the Web, these JavaScript representations have transferred with them. They are much easier for humans to read and much less verbose. They also take up less data, another reason these types of objects have proliferated within mobile devices.
XML is very verbose, which can be good when dealing with complicated data. However, it will add significant bulk to your data packets, and in mobile development, where you have limited bandwidth and you have to deal with slow connections, transferring as little data as possible becomes ever more important. This is why many mobile applications have chosen JSON for encoding and transferring data.
For reference, JSON has the following basic data types available:
String
Number
Boolean
Null
Hash
Array
Many mobile applications need data from the Internet in order to function. If you can build RESTful backend services like the ones mentioned in Chapter 5 and scale them in a PaaS environment, they can be consumed easily and quickly by mobile applications in any environment.
Native iOS applications in Objective-C can get data quickly and easily from metaservices. There are various ways you can approach this process, from building it yourself to leveraging open source or proprietary frameworks to help you.
The first step to writing the code yourself is leveraging iOS’s asynchronous network operations:
Here is an example of what that Objective-C code might look like in practice:
-(void)load{NSURL*myURL=[NSURLURLWithString:@"http://example.com/users"];NSMutableURLRequest*request=[NSMutableURLRequestrequestWithURL:myURLcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:120];[[NSURLConnectionalloc]initWithRequest:requestdelegate:self];}-(void)connection:(NSURLConnection*)connectiondidReceiveData:(NSData*)data{[mutableDataappendData:data];}-(void)connection:(NSURLConnection*)connectiondidReceiveResponse:(NSURLResponse*)response{mutableData=[[NSMutableDataalloc]init];}-(void)connection:(NSURLConnection*)connectiondidFailWithError:(NSError*)error{[mutableDatarelease];[connectionrelease];NSLog(@"Unable to fetch data");}-(void)connectionDidFinishLoading:(NSURLConnection*)connection{NSLog(@"Succeeded! Received %d bytes of data",[mutableDatalength]);NSString*jsonResponse=[[[NSStringalloc]initWithData:mutableDataencoding:NSASCIIStringEncoding]autorelease];// Parse the jsonResponse and feed it to the UI}
As of iOS 5, Apple added native parsing of JSON through the NSJSONSerialization class; however, there are
some open source libraries that can parse JSON even faster in iOS, like JSONKit.
Once the data is grabbed and parsed, there are a number of ways to serve that data to the frontend user experience:
Delegate the controller to the view that now has the data. This is straightforward to implement the view delegation methods, but it does not persist the data on the device.
Persist the data on the device in a plist or archived format.
Persist the data on the device using Apple’s Core Data framework.
Apple’s Core Data framework is Apple’s standard way for iOS apps to persist data on phones. It is used widely for filling the UI components quickly and easily through many parts of the iOS experience.
RestKit is a popular open source framework for iOS that does a lot of the work described above automatically. It will handle the network-grabbing pieces and the JSON parsing, automatically populate the data into Core Data, seed the Core Data objects when you submit them to the App Store, provide an object mapping system, and more. Here is some example code that illustrates how easy it is to integrate example RESTful URL http://example.com/users for adding a user’s concept to your iOS application:
// User.h@interfaceUser:NSObject@property(strong,nonatomic)NSString*name;@end// User.m@implementationUser@synthesizename;@end// MasterViewController.m#import <RestKit/RestKit.h>#import "User.h"...-(void)viewDidLoad{[superviewDidLoad];RKURL*baseURL=[RKURLURLWithBaseURLString:@"http://example.com/users"];RKObjectManager*objectManager=[RKObjectManagerobjectManagerWithBaseURL:baseURL];objectManager.client.baseURL=baseURL;RKObjectMapping*userMapping=[RKObjectMappingmappingForClass:[Userclass]];[userMappingmapKeyPathsToAttributes:@"name",@"name",nil];[objectManager.mappingProvidersetMapping:venueMappingforKeyPath:@"response.users"];[selfsendRequest];}
It is obvious how much easier it is to use a library like this, but you do lose the ability to control a lot of the internal details if you need them.
Android native applications use Java and can also get data quickly and easily from metaservices. As with iOS, there are various ways you can approach this process, from building it yourself to leveraging open source or proprietary frameworks to help you.
The first step to writing the code yourself is leveraging Android’s asynchronous network operations:
Here is an example of what that Java code might look like in practice:
// executed in a Service via new GetRESTData().execute();// http://developer.android.com/reference/android/app/Service.htmlprivateclassGetRESTDataextendsAsyncTask<Void,Void,String>{@OverrideprotectedStringdoInBackground(Void...params){URLurl=newURL("http://example.com/users");URLConnectionurlConnection=url.openConnection();InputStreamin=newBufferedInputStream(urlConnection.getInputStream());BufferedReaderreader=newBufferedReader(newInputStreamReader(in));Stringresult,line=reader.readLine();result=line;while((line=reader.readLine())!=null){result+=line;}in.close();returnresult;}protectedvoidonPostExecute(StringrestResult){// process the JSON string into a Java object// and persist it into a SQLite database}}
Note that you should not implement Android REST methods inside activities. Activities are for user interface and user experience functionality. The code should always start long-running operations from a service; Android services were meant to run this kind of code.
Android has a native parser for JSON through the org.json.JSONObject class; there are also some open source libraries that can parse
JSON in Android, like JSONLib, FlexJSON, and Gson.
Once the data is grabbed and parsed, it needs to be persisted immediately. SQLite is your best friend in Android. You should also use a sync adapter to execute regular checks for new data from your REST services. The sync adapter can change your data-grabbing process from a pull into a push architecture, which will save a ton of battery life.
Like RestKit for iOS, there are REST libraries for Android. In fact, because Android uses Java, you can use the same REST client libraries in your Android native mobile apps as you do your Java web apps. Restlet is one such popular library that can save you time and headaches when getting data from RESTful resources.
There are some good tutorials and books about Restlet; check out the website and Restlet in Action by Jerome Louvel, Thierry Templier, and Thierry Boileau.
Here is what a simple Restlet implementation might look like:
publicinterfaceUserResource{@GetpublicUserretrieve();@Putpublicvoidstore(Useruser);@Deletepublicvoidremove();}ClientResourcecr=newClientResource("http://example.com/users/123");// Get the User objectUserResourceresource=cr.wrap(UserResource.class);Useruser=resource.retrieve();
Restlet manages the JSON parsing and many other aspects, but
your User class will still need to handle
persistence to a SQLite database. For more information about this, take
a look at Android
Cookbook by Ian F. Darwin (specifically Chapter 11,
which handles persisting data and parsing JSON in more detail).
In this chapter, we have seen how easy it is to incorporate dynamic data into mobile applications when there are RESTful metaservices behind the scenes. There are many benefits PaaS brings when you build mobile applications this way. The following sections examine a few of these benefits.
As seen in Chapter 5, building metaservices, which can power mobile or web frontends, is easy to do in Platform-as-a-Service. In fact, building applications in PaaS this way from the beginning is actually a best practice. These services have less code, are easier to maintain, and are easier to scale.
When you use a PaaS to build metaservices, deploying large N-tier clustered servers and managing them takes seconds, not weeks or months.
PaaS makes building and running metaservices faster and easier than ever before.
Scaling metaservices in PaaS is easy. If your app is modular and does not require constant disk access, you can very quickly and easily add more instances, which increases the concurrency levels dramatically. As thousands (or hopefully millions) of people start using your mobile applications, adding capacity is no longer a chore but an API call.
Many PaaS providers even have REST APIs, which you can use to automate the process of scaling.
You might only have 1,000 users, but those users might upload 100,000,000 pictures. Your PaaS provider can make it easy to manage and run the proper scalable backend service to handle both kinds of services fast and effectively.
Once you build your metaservices and launch them on a PaaS, they can be accessed through your iOS, Android, or Windows Phone smartphones and tablets. They can even power your web presence. This is a powerful way to maximize the efficiency of the resources you have when building applications.
To date, we have seen the growth of many different kinds of applications. In some cases, developers have created them in their basements and then leveraged PaaS, or tried to leverage one of the methods that we discussed earlier in this book, such as dedicated hosting. With a bit of luck, they might get featured on one of the app stores. And, as we’ve seen, the ensuing pressure on computing resources can sometimes ruin the developer’s business.
The anticipated proliferation of mobile devices is going to exacerbate these kinds of problems for those who do not adopt PaaS to help them scale their applications. The audience for mobile apps is going to expand drastically, and that is going to make it even more difficult to create scalable backend infrastructures for anything but the simplest of phone applications.