Slide 1

Slide 1 text

John Sheehan CEO, Runscope The rise of distributed applications. Thursday, March 27, 14

Slide 2

Slide 2 text

Software is eating lunch and APIs are for dessert! HYPER MEDIA Thursday, March 27, 14

Slide 3

Slide 3 text

“There's just no getting around it: you're building a distributed system. -- Mark Cavage, ACM Queue Thursday, March 27, 14

Slide 4

Slide 4 text

Mobile & Desktop Apps Web Sites & Applications Internal APIs 3rd-party Service APIs Public APIs Thursday, March 27, 14

Slide 5

Slide 5 text

Mobile & Desktop Apps Web Sites & Applications Internal APIs 3rd-party Service APIs Public APIs fn(){} fn(){} fn(){} fn(){} fn(){} Thursday, March 27, 14

Slide 6

Slide 6 text

fn(){} fn(){} fn(){} fn(){} fn(){} YOUR APPLICATION Thursday, March 27, 14

Slide 7

Slide 7 text

What are the challenges for running an API-driven application? Thursday, March 27, 14

Slide 8

Slide 8 text

CHALLENGE #1 Getting a complete picture of your app. Thursday, March 27, 14

Slide 9

Slide 9 text

Watch and log everything. Thursday, March 27, 14

Slide 10

Slide 10 text

CHALLENGE #2 Managing change. Thursday, March 27, 14

Slide 11

Slide 11 text

Prefer lighter abstractions. Thursday, March 27, 14

Slide 12

Slide 12 text

Think twice about taking a dependency on an SDK. Thursday, March 27, 14

Slide 13

Slide 13 text

Your Code The API API SDK v1 v2 Thursday, March 27, 14

Slide 14

Slide 14 text

Your Code The API API SDK ??? ??? Thursday, March 27, 14

Slide 15

Slide 15 text

SDKs OK: Prototyping No good HTTP Client Building Clients Complex APIs Uses Native APIs Thursday, March 27, 14

Slide 16

Slide 16 text

SDK DANGER: Using more than one Community-built Many dependencies Inactive Thursday, March 27, 14

Slide 17

Slide 17 text

SDK FOR PROVIDERS: Definitely build them! ...for many platforms ...as native as possible ...and well-documented Thursday, March 27, 14

Slide 18

Slide 18 text

HOW WE DO Smarter HTTP client Thin wrappers Thursday, March 27, 14

Slide 19

Slide 19 text

url = "https://ec2-23-212-199-23.us-west-2.amazo resp = requests.get(url) if resp.ok: return resp.json() else: # retry? return None def get_user(id): def main(): user = get_user(id) print user["name"] Thursday, March 27, 14

Slide 20

Slide 20 text

class Identity def get_user(id): url = "service://identity/users/" + id resp = smart_client.get(url) if resp.ok: return User(resp.json()) return AnonymousUser() from Identity import get_user def main(): user = get_user(id) print user.name Auto-locate service Smart retries Thursday, March 27, 14

Slide 21

Slide 21 text

CHALLENGE #3 High-fidelity testing. Thursday, March 27, 14

Slide 22

Slide 22 text

Let’s look at some API testing frameworks. Thursday, March 27, 14

Slide 23

Slide 23 text

require  'rubygems' require  'test/unit' require  'vcr' VCR.configure  do  |c|    c.cassette_library_dir  =  'fixtures/vcr_cassettes'    c.hook_into  :webmock  #  or  :fakeweb end class  VCRTest  <  Test::Unit::TestCase    def  test_example_dot_com        VCR.use_cassette('synopsis')  do              url  =  'http://yourapihere.com'            response  =  Net::HTTP.get_response(URI(url))            assert_match  /Example  domains/,  response.body        end    end end VCR github.com/vcr/vcr Thursday, March 27, 14

Slide 24

Slide 24 text

mocky.io Thursday, March 27, 14

Slide 25

Slide 25 text

frisby.js Thursday, March 27, 14

Slide 26

Slide 26 text

aspec github.com/songkick/aspec # no users have pending notifications GET /users/with-pending-notifications 200 application/json [] # users with events on their calendar have pending notifications POST /users/764/metro-areas/999 204 POST /users/764/artists/123 204 POST /events/5?artist_ids=123&metro_area_id=999 204 POST /events/5/enqueue-notifications 204 GET /users/with-pending-notifications 200 application/json [[764, "ep"]] # users are unique in the response POST /users/764/artists/123 204 POST /users/764/artists/456 204 POST /users/764/metro-areas/999 204 POST /events/5?artist_ids=123,456&metro_area_id=999 204 POST /events/5/enqueue-notifications 204 GET /users/with-pending-notifications 200 application/json [[764, "ep"]] Thursday, March 27, 14

Slide 27

Slide 27 text

service  "http://localhost:4567"  do    def  responds_with_json_where        JSON.parse(response.body)    end    resource  "/lolz"  do        get  do            it  {  responds_with.status  :ok  }            it  {  responds_with_json_where['lolz'].must_be_instance_o            with_query("q=monorail")  do                it  "only  lists  lolz  that  match  the  query"  do                    responds_with_json_where['lolz'].wont_be_empty                    responds_with_json_where['lolz'].each  do  |lol|                        lol['title'].must_match  /monorail/                    end                end            end HyperSpec Thursday, March 27, 14

Slide 28

Slide 28 text

Thursday, March 27, 14

Slide 29

Slide 29 text

THANK YOU API Podcast: trafficandweather.io Try Runscope Free: runscope.com Thursday, March 27, 14