Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Zen and the Art of API Maintenance

Zen and the Art of API Maintenance

Presented at Ultimate Developer's Conference #UDE2013 on November 22, 2013

John Sheehan

November 22, 2013
Tweet

More Decks by John Sheehan

Other Decks in Technology

Transcript

  1. John Sheehan
    CEO, Runscope
    Building API
    integrations
    you can live with.
    Friday, November 22, 13

    View Slide

  2. “There's just no
    getting around it:
    you're building a
    distributed system.
    -- Mark Cavage, ACM Queue
    Friday, November 22, 13

    View Slide

  3. Mobile &
    Desktop
    Apps
    Web Sites &
    Applications
    Internal APIs
    3rd-party
    Service APIs
    Public APIs
    Friday, November 22, 13

    View Slide

  4. Mobile &
    Desktop
    Apps
    Web Sites &
    Applications
    Internal APIs
    3rd-party
    Service APIs
    Public APIs
    fn(){}
    fn(){}
    fn(){}
    fn(){}
    fn(){}
    Friday, November 22, 13

    View Slide

  5. fn(){} fn(){}
    fn(){}
    fn(){} fn(){}
    YOUR APPLICATION
    Friday, November 22, 13

    View Slide

  6. What are the
    challenges for running
    an API-driven
    application?
    Friday, November 22, 13

    View Slide

  7. CHALLENGE #1
    Getting a complete
    picture of your app.
    Friday, November 22, 13

    View Slide

  8. Keep an eye on
    everything.
    Friday, November 22, 13

    View Slide

  9. CHALLENGE #2
    Managing
    change.
    Friday, November 22, 13

    View Slide

  10. Prefer lighter
    abstractions.
    Friday, November 22, 13

    View Slide

  11. Think twice about
    taking a dependency
    on an SDK.
    Friday, November 22, 13

    View Slide

  12. Your Code
    The API
    API SDK
    v1
    v2
    Friday, November 22, 13

    View Slide

  13. Your Code
    The API
    API SDK
    ???
    ???
    Friday, November 22, 13

    View Slide

  14. SDKs OK:
    Prototyping
    No good HTTP Client
    Building Clients
    Complex APIs
    Uses Native APIs
    Friday, November 22, 13

    View Slide

  15. SDK DANGER:
    Using more than one
    Community-built
    Many dependencies
    Inactive
    Friday, November 22, 13

    View Slide

  16. HOW WE DO
    Smarter HTTP client
    Thin wrappers
    Friday, November 22, 13

    View Slide

  17. 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"]
    Friday, November 22, 13

    View Slide

  18. 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
    Friday, November 22, 13

    View Slide

  19. CHALLENGE #3
    High-fidelity
    testing.
    Friday, November 22, 13

    View Slide

  20. Let’s look at some API
    testing frameworks.
    Friday, November 22, 13

    View Slide

  21. 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
    Friday, November 22, 13

    View Slide

  22. mocky.io
    Friday, November 22, 13

    View Slide

  23. frisby.js
    Friday, November 22, 13

    View Slide

  24. 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"]]
    Friday, November 22, 13

    View Slide

  25. 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
    Friday, November 22, 13

    View Slide

  26. Friday, November 22, 13

    View Slide

  27. Friday, November 22, 13

    View Slide

  28. Friday, November 22, 13

    View Slide

  29. Friday, November 22, 13

    View Slide

  30. Free sign up, free t-shirt:
    runscope.com/ts
    Friday, November 22, 13

    View Slide