The Anatomy of Apps
How 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
New!

       IRC Channel
         #api-craft
App    App             App       World of          API   Internal
               App                          API
User   Store         Developer    APIs            Team   Systems
Dogs API

/dogs

/owners



Authorization

OAuth 2.0




RESTful API Design - Second Edition
http://www.youtube.com/watch?v=QpAhXa12xvU
Build an iPhone App, an Android App and a
Facebook Web App*




*Ruby on Rails app hosted on Heroku
http://devcenter.heroku.com/articles/facebook
App    App             App       World of          API   Internal
               App                          API
User   Store         Developer    APIs            Team   Systems
Start with a basic HTTP request
Android

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



iOS

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL
  URLWithString:@"http://api.apizoo.com/v1/dogs"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request
  returningResponse:nil error:nil];



Ruby on Rails

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

JSONObject dogs = new JSONObject(response);




iOS

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




Ruby on Rails

require 'yajl'
parser = Yajl::Parser.new
dogs = parser.parse(response) # returns a hash
Resource Object Mapping
Route
Map
Use
Android Spring Mobile




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




Map
// Handled with introspection
Android Spring Mobile




Use
Dog dog = responseEntity.getBody()
iOS RestKit

Route

#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)"];
iOS RestKit



Map

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


Use

Dog* dog = [Dog object];
dog.name = @"Rover";
Dog.color = @"red";

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

[[RKObjectManager sharedManager] deleteObject:dog delegate:self];
Ruby on Rails ActiveResource




Route

resource :dogs
Ruby on Rails ActiveResource




Map

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




Use

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

dog.save

dog.destroy
Cache the response in a database
Android Jersey + Jackson




Usage
Roll your own
iOS RestKit + Core Data


Usage

#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
Ruby on Rails ActiveResource + ActiveRecord


Usage

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

class Dog < ActiveRecord::Base
 # the before methods call DogResource methods
 before_create :create_resource
 before_update :update_resource
 before_destroy :destroy_resource
end
Simple to do list
Problem: we want new capabilities in our app not
supported by APIs.
Usergrid - Data & Queries
http://www.youtube.com/watch?v=zLl56sU5Bt0
Android

usergrid_ sdk




iOS

Use RESTKit




Ruby on Rails

Probably not applicable
What about offline cases
Android

Roll your own


iOS

-(BOOL)reachable {
Reachability *r = [Reachability
    reachabilityWithHostName:@"api.apizoo.com/v1"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if(internetStatus == NotReachable) {
 return NO;
}
return YES;
}



Ruby on Rails

Probably not applicable
Get authorization out of the way




Assumption: the APIs we consume use OAuth 2
Android

Roll your own
iOS RestKit

RKObjectManager* objectManager = [RKObjectManager sharedManager];
objectManager.client.baseURL = @”api.apizoo.com/v1";
objectManager.client.OAuth2AccessToken = @"YOUR ACCESS TOKEN";
objectManager.client.authenticationType =
  RKRequestAuthenticationTypeOAuth2;
Ruby on Rails Oauth Gem

@consumer=OAuth::Consumer.new("key","secret", site: "api.apizoo.com/v1")
@request_token=@consumer.get_request_token
session[:request_token]=@request_token
redirect_to @request_token.authorize_url
@access_token=@request_token.get_access_token
Android
Built-in JSON, etc.
Spring Mobile (bundles Jersey & Jackson)

iOS
JSONKit
RestKit
Core Data

Ruby on Rails
YAJL
ActiveResource
Oauth
Coming Up: March Miniseries on Apps & APIs
Questions?
THANK YOU
Subscribe to API webinars at:
youtube.com/apigee
THANK YOU
Chat on IRC
#api-craft
THANK YOU
Questions and ideas to:
groups.google.com/group/api-craft
THANK YOU
Contact us at:

@edanuff
ed@apigee.com


@sramji
sramji@apigee.com

@landlessness
brian@apigee.com

The Anatomy of Apps - How iPhone, Android & Facebook Apps Consume APIs

  • 1.
    The Anatomy ofApps How iPhone, Android & Facebook Apps Consume APIs Ed Anuff @edanuff Sam Ramji @sramji Brian Mulloy @landlessness Apigee @apigee
  • 2.
  • 3.
  • 4.
    New! IRC Channel #api-craft
  • 5.
    App App App World of API Internal App API User Store Developer APIs Team Systems
  • 6.
    Dogs API /dogs /owners Authorization OAuth 2.0 RESTfulAPI Design - Second Edition http://www.youtube.com/watch?v=QpAhXa12xvU
  • 7.
    Build an iPhoneApp, an Android App and a Facebook Web App* *Ruby on Rails app hosted on Heroku http://devcenter.heroku.com/articles/facebook
  • 8.
    App App App World of API Internal App API User Store Developer APIs Team Systems
  • 9.
    Start with abasic HTTP request
  • 10.
    Android HttpClient client =new DefaultHttpClient(); HttpGet httpGet = new HttpGet("http://api.apizoo.com/v1/dogs"); HttpResponse response = client.execute(httpGet); iOS NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://api.apizoo.com/v1/dogs"]]; NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; Ruby on Rails require 'net/http' response = Net::HTTP.get(‘api.apizoo.com/v1’, ‘/dogs’)
  • 11.
  • 12.
    Android JSONObject dogs =new JSONObject(response); iOS import "JSONKit.h" NSDictionary *dogs = [response objectFromData]; Ruby on Rails require 'yajl' parser = Yajl::Parser.new dogs = parser.parse(response) # returns a hash
  • 13.
  • 14.
  • 15.
    Android Spring Mobile Route requestEntity= new HttpEntity<Object>(requestHeaders); ResponseEntity<Dog> responseEntity = restTemplate.exchange("http://api.apizoo.com/v1/dogs/15", HttpMethod.GET, requestEntity, Dog.class);
  • 16.
    Android Spring Mobile Map //Handled with introspection
  • 17.
    Android Spring Mobile Use Dogdog = responseEntity.getBody()
  • 18.
    iOS RestKit Route #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)"];
  • 19.
    iOS RestKit Map @implementation Dog +(NSDictionary*)elementToPropertyMappings { return [NSDictionary dictionaryWithKeysAndObjects: @"name", @"color", nil]; } @end
  • 20.
    iOS RestKit Use Dog* dog= [Dog object]; dog.name = @"Rover"; Dog.color = @"red"; [[RKObjectManager sharedManager] postObject:dog delegate:self]; [[RKObjectManager sharedManager] deleteObject:dog delegate:self];
  • 21.
    Ruby on RailsActiveResource Route resource :dogs
  • 22.
    Ruby on RailsActiveResource Map class Dog < ActiveResource::Base self.site = "http://api.apizoo.com/v1" end
  • 23.
    Ruby on RailsActiveResource Use dog = Dog.new name: ‘Rover’, color: ‘red’ dog.save dog.destroy
  • 24.
    Cache the responsein a database
  • 25.
    Android Jersey +Jackson Usage Roll your own
  • 26.
    iOS RestKit +Core Data Usage #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
  • 27.
    Ruby on RailsActiveResource + ActiveRecord Usage class DogResource < ActiveResource::Base self.site = http://api.apizoo.com/v1 end class Dog < ActiveRecord::Base # the before methods call DogResource methods before_create :create_resource before_update :update_resource before_destroy :destroy_resource end
  • 28.
  • 29.
    Problem: we wantnew capabilities in our app not supported by APIs.
  • 30.
    Usergrid - Data& Queries http://www.youtube.com/watch?v=zLl56sU5Bt0
  • 31.
    Android usergrid_ sdk iOS Use RESTKit Rubyon Rails Probably not applicable
  • 32.
  • 33.
    Android Roll your own iOS -(BOOL)reachable{ Reachability *r = [Reachability reachabilityWithHostName:@"api.apizoo.com/v1"]; NetworkStatus internetStatus = [r currentReachabilityStatus]; if(internetStatus == NotReachable) { return NO; } return YES; } Ruby on Rails Probably not applicable
  • 34.
    Get authorization outof the way Assumption: the APIs we consume use OAuth 2
  • 35.
  • 36.
    iOS RestKit RKObjectManager* objectManager= [RKObjectManager sharedManager]; objectManager.client.baseURL = @”api.apizoo.com/v1"; objectManager.client.OAuth2AccessToken = @"YOUR ACCESS TOKEN"; objectManager.client.authenticationType = RKRequestAuthenticationTypeOAuth2;
  • 37.
    Ruby on RailsOauth Gem @consumer=OAuth::Consumer.new("key","secret", site: "api.apizoo.com/v1") @request_token=@consumer.get_request_token session[:request_token]=@request_token redirect_to @request_token.authorize_url @access_token=@request_token.get_access_token
  • 38.
    Android Built-in JSON, etc. SpringMobile (bundles Jersey & Jackson) iOS JSONKit RestKit Core Data Ruby on Rails YAJL ActiveResource Oauth
  • 39.
    Coming Up: MarchMiniseries on Apps & APIs
  • 40.
  • 41.
    THANK YOU Subscribe toAPI webinars at: youtube.com/apigee
  • 42.
    THANK YOU Chat onIRC #api-craft
  • 43.
    THANK YOU Questions andideas to: groups.google.com/group/api-craft
  • 44.
    THANK YOU Contact usat: @edanuff ed@apigee.com @sramji sramji@apigee.com @landlessness brian@apigee.com

Editor's Notes

  • #2 Creative Commons Attribution-Share Alike 3.0 United States License
  • #13 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #16 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #17 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #18 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #19 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #20 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #21 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #22 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #23 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #24 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #26 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #27 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #28 Android &amp; iOS default response is a hash/dictionaryRuby on Rails
  • #34 iOSFun factoid: the app store will reject your app if you don’t properly test your app using the reachability APIAndroidSearch around for Reachability - Connectivity Manager
  • #35 If you provide and consume the api then auth is what u make it.Oauth 2 is a standard but not too heavyAbout 70% of the reason folks go to a special purpose built client library is auth, the second is object marshaling.The standard clients start to screw you over…Parameter signing are a nightmare for the app developer. RestKit
  • #37 AndroidSUN JerseySpring MobileTradeoffs are around the App SizeForOauth: do the flow with the web browser but oauth 2 is a really pragmatic spec you can also pass a username and password. It will be up to the app. Client id and the client token. Get back an access token either in the header or as a param.
  • #38 AndroidSUN JerseySpring MobileTradeoffs are around the App SizeForOauth: do the flow with the web browser but oauth 2 is a really pragmatic spec you can also pass a username and password. It will be up to the app. Client id and the client token. Get back an access token either in the header or as a param.