The rise of distributed applications.

The rise of distributed applications.

API Strategy and Practice 2014 in Amsterdam

54b75f6fbf4434162bfcda6b0cb9b86b?s=128

John Sheehan

March 27, 2014
Tweet

Transcript

  1. John Sheehan CEO, Runscope The rise of distributed applications. Thursday,

    March 27, 14
  2. Software is eating lunch and APIs are for dessert! HYPER

    MEDIA Thursday, March 27, 14
  3. “There's just no getting around it: you're building a distributed

    system. -- Mark Cavage, ACM Queue Thursday, March 27, 14
  4. Mobile & Desktop Apps Web Sites & Applications Internal APIs

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

    3rd-party Service APIs Public APIs fn(){} fn(){} fn(){} fn(){} fn(){} Thursday, March 27, 14
  6. fn(){} fn(){} fn(){} fn(){} fn(){} YOUR APPLICATION Thursday, March 27,

    14
  7. What are the challenges for running an API-driven application? Thursday,

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

    March 27, 14
  9. Watch and log everything. Thursday, March 27, 14

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

  11. Prefer lighter abstractions. Thursday, March 27, 14

  12. Think twice about taking a dependency on an SDK. Thursday,

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

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

    27, 14
  15. SDKs OK: Prototyping No good HTTP Client Building Clients Complex

    APIs Uses Native APIs Thursday, March 27, 14
  16. SDK DANGER: Using more than one Community-built Many dependencies Inactive

    Thursday, March 27, 14
  17. SDK FOR PROVIDERS: Definitely build them! ...for many platforms ...as

    native as possible ...and well-documented Thursday, March 27, 14
  18. HOW WE DO Smarter HTTP client Thin wrappers Thursday, March

    27, 14
  19. 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
  20. 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
  21. CHALLENGE #3 High-fidelity testing. Thursday, March 27, 14

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

    14
  23. 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
  24. mocky.io Thursday, March 27, 14

  25. frisby.js Thursday, March 27, 14

  26. 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
  27. 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
  28. Thursday, March 27, 14

  29. THANK YOU API Podcast: trafficandweather.io Try Runscope Free: runscope.com Thursday,

    March 27, 14