Nordic APIs Tour 2014
Holger Reinhardt
@hlgr360
holger.reinhardt@ca.com
http://www.flickr.com/photos/jurvetson/21470089/
You	
  want	
  a	
  Library	
  	
  
with	
  that	
  (API)?	
  
Designing	
  an	
  API	
  is	
  easy	
  	
  
Effec%ve	
  API	
  design	
  is	
  difficult	
  
•  Informaton
•  Product
•  Service
Business
Asset
•  API
•  SLA
•  EULA
API Provider
•  Building
App
Developer
•  Using API
Application
•  Using App
End-User
The	
  API	
  Value	
  Chain	
  
•  Informaton
•  Product
•  Service
Business
Asset
•  API
•  SLA
•  EULA
API Provider
•  Building
App
Developer
•  Using API
Application
•  Using App
End-User
Effec%ve	
  API	
  Design	
  
And	
  this	
  is	
  when	
  Someone	
  usually	
  asks	
  
A	
  story	
  about	
  two	
  APIs	
  
I	
  love	
  it	
  
I	
  wanted	
  Javascript,	
  but	
  got	
  PHP	
  
I	
  wanted	
  Client-­‐side,	
  but	
  got	
  Server-­‐side	
  
- need to install peck or pearl on my Mac
http://pear.php.net/manual/en/installation.getting.php
- went back to documentation to install oauth
extension, needed autoconf - tried another way
http://stackoverflow.com/questions/5536195/install-pecl-
on-mac-os-x-10-6
- still required autoconf
http://mac-dev-env.patrickbougie.com/autoconf/
-  Error: PECL: configuration option "php_ini" is
not set to php.ini location
http://arcadian83.livejournal.com/16386.html
=> Ready to run php lib from fitbit website
- Enable php
http://editrocket.com/articles/php_apache_mac.html
- Enable apache server
http://reviews.cnet.com/8301-13727_7-57481978-263/how-to-
enable-web-sharing-in-os-x-mountain-lion/
-  sudo apachectl start
=> Ready to start playing with the php lib
small	
  annoyances	
  add	
  up	
  	
  
to	
  create	
  a	
  poor	
  experience	
  
And	
  that	
  PHP	
  code	
  looks	
  complex	
  
<?php
// Base URL
$baseUrl = 'http://api.fitbit.com';
// Request token path
$req_url = $baseUrl . '/oauth/request_token';
// Authorization path
$authurl = $baseUrl . '/oauth/authorize';
// Access token path
$acc_url = $baseUrl . '/oauth/access_token';
// Consumer key
$conskey = 'local-fitbit-example-php-client-application';
// Consumer secret
$conssec = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// Fitbit API call (get activities for specified date)
$apiCall = "http://api.fitbit.com/1/user/-/activities/date/2014-01-25.xml";
// HR: callback url
$callbackUrl = "http://localhost/~h_reinhardt/fitbit/php/
completeAuthorization.php";
// Start session to store the information between calls
session_start();
// In state=1 the next request should include an oauth_token.
// If it doesn't go back to 0
if ( !isset($_GET['oauth_token']) && $_SESSION['state']==1 )
$_SESSION['state'] = 0;
try
{
// Create OAuth object
$oauth = new OAuth($conskey,
$conssec,OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_AUT
HORIZATION);
// Enable ouath debug (should be disabled in production)
$oauth->enableDebug();
if ( $_SESSION['state'] == 0 )
{
// Getting request token. Callback URL is the Absolute URL to which
the server provder will redirect the User back when the obtaining user
authorization step is completed.
$request_token_info = $oauth->getRequestToken($req_url,
$callbackUrl);
// Storing key and state in a session.
$_SESSION['secret'] = $request_token_info['oauth_token_secret'];
$_SESSION['state'] = 1;
// Redirect to the authorization.
header('Location: '.$authurl.'?oauth_token='.
$request_token_info['oauth_token']);
exit;
}
else if ( $_SESSION['state']==1 )
{
// Authorized. Getting access token and secret
$oauth->setToken($_GET['oauth_token'],$_SESSION['secret']);
$access_token_info = $oauth->getAccessToken($acc_url);
// Storing key and state in a session.
$_SESSION['state'] = 2;
$_SESSION['token'] = $access_token_info['oauth_token'];
$_SESSION['secret'] = $access_token_info['oauth_token_secret'];
}
// Setting asccess token to the OAuth object
$oauth->setToken($_SESSION['token'],$_SESSION['secret']);
// Performing API call
$oauth->fetch($apiCall);
// Getting last response
$response = $oauth->getLastResponse();
// Initializing the simple_xml object using API response
But	
  that	
  SDK	
  looks	
  sHcky	
  and	
  heavy	
  
<?php
require 'php-sdk/src/temboo.php';
// Instantiate the Choreo, using a previously instantiated Temboo_Session
object, eg:
// $session = new Temboo_Session('hlgr360', 'APP_NAME', 'APP_KEY');
$session = new Temboo_Session('hlgr360', 'myFirstApp',
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
$getActivities = new Fitbit_Activities_GetActivities($session);
// Get an input object for the Choreo
$getActivitiesInputs = $getActivities->newInputs();
// Set credential to use for execution
$getActivitiesInputs->setCredential('apiacademy');
// Set inputs
$getActivitiesInputs->setDate("2014-01-25")->setResponseFormat("xml");
// Execute Choreo and get results
$getActivitiesResults = $getActivities->execute($getActivitiesInputs)-
>getResults();
// Initializing the simple_xml object using API response
$xml = simplexml_load_string($getActivitiesResults->getResponse());
?>
$(document).ready( function () {
OAuth.initialize(’xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’);
// Using popup (option 1)
OAuth.popup('fitbit', function(error, result) {
if (error) {
console.log(err); // do something with error
return;
};
result.get("/1/user/-/profile.json").done(function(res) {
console.log("Hello, ", res);
var $img = $("<img>",{src: res.user.avatar});
$(".avatar").append($img);
$(".name").append(res.user.fullName);
$(".dateofbirth").append(res.user.dateOfBirth);
$(".metric").append(res.user.distanceUnit);
$(".stridewalking").append(res.user.strideLengthWalking);
$(".striderunning").append(res.user.strideLengthRunning);
});
});
// Using redirection (option 2)
//OAuth.redirect('fitbit', "callback/url");
});
fitbit-profile.html fitbit.js
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Fitbit client-side example using OAuth.io</title>
</head>
<body>
<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="oauth.js"></script>
<script type="text/javascript" src="fitjs.js"></script>
<!-- Show some basic profile -->
<div class="avatar"/>Avatar: </div></br>
<div class="name">Name: </div></br>
<div class="dateofbirth">Born: </div></br>
<div class="metric">Unit: </div></br>
<div class="stridewalking">Stride (walking): </div></br>
<div class="striderunning">Stride (running): </div></br>
</body>
</html>
Using	
  a	
  SDK	
  might	
  be	
  easier,	
  unHl	
  it	
  isn’t	
  
 
SDK	
  Benefits	
  
	
  
•  Time	
  to	
  First	
  Use	
  (Developer	
  On-­‐boarding)	
  
•  Best	
  client	
  for	
  your	
  API	
  
•  Simplify	
  API	
  design	
  by	
  extracHng	
  business	
  
logic	
  into	
  the	
  SDK	
  
•  Strongly-­‐typed	
  language	
  representaHon	
  	
  
 
SDK	
  Drawbacks	
  
	
  
•  Making	
  API	
  design	
  an	
  aPerthought	
  
•  Picking	
  plaQorm	
  and	
  framework	
  winners	
  
•  3rd	
  party	
  framework	
  dependencies	
  
•  Version	
  dependencies	
  between	
  SDK	
  and	
  API	
  
•  SDK	
  carry-­‐on	
  weight	
  
•  Long-­‐term	
  support	
  costs	
  
 
Using	
  SDKs	
  in	
  Produc%on?	
  
	
  
•  InstrumentaHon?	
  
•  Metrics?	
  
•  Error	
  Handling	
  and	
  Idempotency?	
  
•  Performance	
  and	
  Persistent	
  ConnecHons?	
  
•  Just	
  Grep?	
  
•  Just	
  Patch?	
  
For a more detailed discussion see http://brandur.org/sdk
 
When	
  to	
  consider	
  SDKs?	
  
	
  
•  Time-­‐To-­‐First-­‐Use	
  
•  Best	
  client	
  for	
  your	
  API	
  
•  Small	
  Group	
  of	
  Known	
  Users	
  (Private	
  or	
  
Partner	
  APIs)	
  
•  Developer	
  ExpectaHons	
  
 
Provide	
  SDKs	
  for	
  on-­‐boarding	
  
TransiHon	
  to	
  Web-­‐APIs	
  for	
  produc%on	
  

Do you want a SDK with that API? (Nordic APIS April 2014)

  • 1.
    Nordic APIs Tour2014 Holger Reinhardt @hlgr360 holger.reinhardt@ca.com
  • 2.
  • 3.
    Designing  an  API  is  easy     Effec%ve  API  design  is  difficult  
  • 4.
    •  Informaton •  Product • Service Business Asset •  API •  SLA •  EULA API Provider •  Building App Developer •  Using API Application •  Using App End-User The  API  Value  Chain  
  • 5.
    •  Informaton •  Product • Service Business Asset •  API •  SLA •  EULA API Provider •  Building App Developer •  Using API Application •  Using App End-User Effec%ve  API  Design  
  • 6.
    And  this  is  when  Someone  usually  asks  
  • 8.
    A  story  about  two  APIs  
  • 11.
  • 14.
    I  wanted  Javascript,  but  got  PHP  
  • 15.
    I  wanted  Client-­‐side,  but  got  Server-­‐side  
  • 16.
    - need toinstall peck or pearl on my Mac http://pear.php.net/manual/en/installation.getting.php - went back to documentation to install oauth extension, needed autoconf - tried another way http://stackoverflow.com/questions/5536195/install-pecl- on-mac-os-x-10-6 - still required autoconf http://mac-dev-env.patrickbougie.com/autoconf/ -  Error: PECL: configuration option "php_ini" is not set to php.ini location http://arcadian83.livejournal.com/16386.html => Ready to run php lib from fitbit website
  • 17.
    - Enable php http://editrocket.com/articles/php_apache_mac.html -Enable apache server http://reviews.cnet.com/8301-13727_7-57481978-263/how-to- enable-web-sharing-in-os-x-mountain-lion/ -  sudo apachectl start => Ready to start playing with the php lib
  • 18.
    small  annoyances  add  up     to  create  a  poor  experience  
  • 19.
    And  that  PHP  code  looks  complex  
  • 20.
    <?php // Base URL $baseUrl= 'http://api.fitbit.com'; // Request token path $req_url = $baseUrl . '/oauth/request_token'; // Authorization path $authurl = $baseUrl . '/oauth/authorize'; // Access token path $acc_url = $baseUrl . '/oauth/access_token'; // Consumer key $conskey = 'local-fitbit-example-php-client-application'; // Consumer secret $conssec = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // Fitbit API call (get activities for specified date) $apiCall = "http://api.fitbit.com/1/user/-/activities/date/2014-01-25.xml"; // HR: callback url $callbackUrl = "http://localhost/~h_reinhardt/fitbit/php/ completeAuthorization.php"; // Start session to store the information between calls session_start(); // In state=1 the next request should include an oauth_token. // If it doesn't go back to 0 if ( !isset($_GET['oauth_token']) && $_SESSION['state']==1 ) $_SESSION['state'] = 0; try { // Create OAuth object $oauth = new OAuth($conskey, $conssec,OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_AUT HORIZATION); // Enable ouath debug (should be disabled in production) $oauth->enableDebug(); if ( $_SESSION['state'] == 0 ) { // Getting request token. Callback URL is the Absolute URL to which the server provder will redirect the User back when the obtaining user authorization step is completed. $request_token_info = $oauth->getRequestToken($req_url, $callbackUrl); // Storing key and state in a session. $_SESSION['secret'] = $request_token_info['oauth_token_secret']; $_SESSION['state'] = 1; // Redirect to the authorization. header('Location: '.$authurl.'?oauth_token='. $request_token_info['oauth_token']); exit; } else if ( $_SESSION['state']==1 ) { // Authorized. Getting access token and secret $oauth->setToken($_GET['oauth_token'],$_SESSION['secret']); $access_token_info = $oauth->getAccessToken($acc_url); // Storing key and state in a session. $_SESSION['state'] = 2; $_SESSION['token'] = $access_token_info['oauth_token']; $_SESSION['secret'] = $access_token_info['oauth_token_secret']; } // Setting asccess token to the OAuth object $oauth->setToken($_SESSION['token'],$_SESSION['secret']); // Performing API call $oauth->fetch($apiCall); // Getting last response $response = $oauth->getLastResponse(); // Initializing the simple_xml object using API response
  • 22.
    But  that  SDK  looks  sHcky  and  heavy  
  • 23.
    <?php require 'php-sdk/src/temboo.php'; // Instantiatethe Choreo, using a previously instantiated Temboo_Session object, eg: // $session = new Temboo_Session('hlgr360', 'APP_NAME', 'APP_KEY'); $session = new Temboo_Session('hlgr360', 'myFirstApp', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); $getActivities = new Fitbit_Activities_GetActivities($session); // Get an input object for the Choreo $getActivitiesInputs = $getActivities->newInputs(); // Set credential to use for execution $getActivitiesInputs->setCredential('apiacademy'); // Set inputs $getActivitiesInputs->setDate("2014-01-25")->setResponseFormat("xml"); // Execute Choreo and get results $getActivitiesResults = $getActivities->execute($getActivitiesInputs)- >getResults(); // Initializing the simple_xml object using API response $xml = simplexml_load_string($getActivitiesResults->getResponse()); ?>
  • 26.
    $(document).ready( function (){ OAuth.initialize(’xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’); // Using popup (option 1) OAuth.popup('fitbit', function(error, result) { if (error) { console.log(err); // do something with error return; }; result.get("/1/user/-/profile.json").done(function(res) { console.log("Hello, ", res); var $img = $("<img>",{src: res.user.avatar}); $(".avatar").append($img); $(".name").append(res.user.fullName); $(".dateofbirth").append(res.user.dateOfBirth); $(".metric").append(res.user.distanceUnit); $(".stridewalking").append(res.user.strideLengthWalking); $(".striderunning").append(res.user.strideLengthRunning); }); }); // Using redirection (option 2) //OAuth.redirect('fitbit', "callback/url"); }); fitbit-profile.html fitbit.js <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Fitbit client-side example using OAuth.io</title> </head> <body> <script type="text/javascript" src="jquery-1.10.2.min.js"></script> <script type="text/javascript" src="oauth.js"></script> <script type="text/javascript" src="fitjs.js"></script> <!-- Show some basic profile --> <div class="avatar"/>Avatar: </div></br> <div class="name">Name: </div></br> <div class="dateofbirth">Born: </div></br> <div class="metric">Unit: </div></br> <div class="stridewalking">Stride (walking): </div></br> <div class="striderunning">Stride (running): </div></br> </body> </html>
  • 27.
    Using  a  SDK  might  be  easier,  unHl  it  isn’t  
  • 28.
      SDK  Benefits     •  Time  to  First  Use  (Developer  On-­‐boarding)   •  Best  client  for  your  API   •  Simplify  API  design  by  extracHng  business   logic  into  the  SDK   •  Strongly-­‐typed  language  representaHon    
  • 29.
      SDK  Drawbacks     •  Making  API  design  an  aPerthought   •  Picking  plaQorm  and  framework  winners   •  3rd  party  framework  dependencies   •  Version  dependencies  between  SDK  and  API   •  SDK  carry-­‐on  weight   •  Long-­‐term  support  costs  
  • 30.
      Using  SDKs  in  Produc%on?     •  InstrumentaHon?   •  Metrics?   •  Error  Handling  and  Idempotency?   •  Performance  and  Persistent  ConnecHons?   •  Just  Grep?   •  Just  Patch?   For a more detailed discussion see http://brandur.org/sdk
  • 31.
      When  to  consider  SDKs?     •  Time-­‐To-­‐First-­‐Use   •  Best  client  for  your  API   •  Small  Group  of  Known  Users  (Private  or   Partner  APIs)   •  Developer  ExpectaHons  
  • 32.
      Provide  SDKs  for  on-­‐boarding   TransiHon  to  Web-­‐APIs  for  produc%on