Anatomy of Apps

Preview:

Citation preview

The Anatomy of AppsHow iPhone, Android & Facebook Apps Consume APIs

Ed Anuff@edanuff

Sam Ramji@sramji

Brian Mulloy@landlessness Apigee

@apigee

groups.google.com/group/api-craft

youtube.com/apigee

IRC Channel#api-craft

New!

AppUser

APITeamAPIApp World of

APIsApp

StoreInternalSystems

AppDeveloper

Build an iPhone App, an Android App and a Facebook Web App*

*Ruby on Rails app hosted on Herokuhttp://devcenter.heroku.com/articles/facebook

AppUser

APITeamAPIApp World of

APIsApp

StoreInternalSystems

AppDeveloper

Start with a basic HTTP request

HttpClient client = new DefaultHttpClient();HttpGet httpGet = new HttpGet("http://api.apizoo.com/v1/dogs");

HttpResponse response = client.execute(httpGet);

Android

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://api.apizoo.com/v1/dogs"]];

NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

iOS

require 'net/http'response = Net::HTTP.get(‘api.apizoo.com/v1’, ‘/dogs’)

Ruby on Rails

Parse the data

JSONObject dogs = new JSONObject(response);

Android

import "JSONKit.h"NSDictionary *dogs = [response objectFromData];

iOS

require 'yajl'parser = Yajl::Parser.newdogs = parser.parse(response) # returns a hash

Ruby on Rails

Resource Object Mapping

RouteMapUse

requestEntity = new HttpEntity<Object>(requestHeaders);ResponseEntity<Dog> responseEntity = restTemplate.exchange("http://api.apizoo.com/v1/dogs/15", HttpMethod.GET, requestEntity, Dog.class);

Route

Android Spring Mobile

// Handled with introspection

Map

Android Spring Mobile

Dog dog = responseEntity.getBody()

Use

Android Spring Mobile

#import <RestKit/RestKit.h>RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://api.apizoo.com/v1"];

RKDynamicRouter* router = [[RKDynamicRouter new] autorelease];

manager.router = router;

[router routeClass:[Dog class] toResourcePath:@"/dogs" forMethod:RKRequestMethodPOST];

[router routeClass:[Dog class] toResourcePath:@"/dogs/(dogID)"];

Route

iOS RestKit

@implementation Dog+ (NSDictionary*)elementToPropertyMappings { return [NSDictionary dictionaryWithKeysAndObjects: @"name", @"color", nil];}@end

Map

iOS RestKit

Dog* dog = [Dog object]; dog.name = @"Rover";Dog.color = @"red"; [[RKObjectManager sharedManager] postObject:dog delegate:self];

[[RKObjectManager sharedManager] deleteObject:dog delegate:self];

Use

iOS RestKit

resource :dogs

Route

Ruby on Rails ActiveResource

class Dog < ActiveResource::Base self.site = "http://api.apizoo.com/v1"end

Map

Ruby on Rails ActiveResource

dog = Dog.new name: ‘Rover’, color: ‘red’

dog.save

dog.destroy

Use

Ruby on Rails ActiveResource

Cache the response in a database

Roll your own

Usage

Android Jersey + Jackson

#import <RestKit/CoreData/CoreData.h>RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://api.apizoo.com/v1"];

manager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"DogApp.sqlite"];

@implementation Dog + (NSString*)primaryKeyProperty { return @"dogID"; } @end

Usage

iOS RestKit + Core Data

class DogResource < ActiveResource::Base self.site = http://api.apizoo.com/v1end

class Dog < ActiveRecord::Base # the before methods call DogResource methods before_create :create_resource before_update :update_resource before_destroy :destroy_resourceend

Usage

Ruby on Rails ActiveResource + ActiveRecord

Simple to do list

Problem: we want new capabilities in our app not supported by APIs.

usergrid_ sdk

Android

Use RESTKit

iOS

Probably not applicable

Ruby on Rails

What about offline cases

Roll your own

Android

-(BOOL)reachable {Reachability *r = [Reachability reachabilityWithHostName:@"api.apizoo.com/v1"];

NetworkStatus internetStatus = [r currentReachabilityStatus];

if(internetStatus == NotReachable) { return NO;}return YES;}

iOS

Probably not applicable

Ruby on Rails

Get authorization out of the way

Assumption: the APIs we consume use OAuth 2

Roll your own

Android

RKObjectManager* objectManager = [RKObjectManager sharedManager];

objectManager.client.baseURL = @”api.apizoo.com/v1";objectManager.client.OAuth2AccessToken = @"YOUR ACCESS TOKEN";

objectManager.client.authenticationType = RKRequestAuthenticationTypeOAuth2;

iOS RestKit

@consumer=OAuth::Consumer.new("key","secret", site: "api.apizoo.com/v1")

@request_token=@consumer.get_request_tokensession[:request_token]=@request_tokenredirect_to @request_token.authorize_url@access_token=@request_token.get_access_token

Ruby on Rails Oauth Gem

AndroidBuilt-in JSON, etc.Spring Mobile (bundles Jersey & Jackson)

iOSJSONKitRestKitCore Data

Ruby on RailsYAJLActiveResourceOauth

Coming Up: March Miniseries on Apps & APIs

Questions?

THANK YOUSubscribe to API webinars at:youtube.com/apigee

THANK YOUChat on IRC#api-craft

THANK YOUQuestions and ideas to:groups.google.com/group/api-craft

THANK YOUContact us at:

@edanuffed@apigee.com

@sramjisramji@apigee.com

@landlessnessbrian@apigee.com

Recommended