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

Zen and the Art of API Maintenance

John Sheehan
November 22, 2013

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. “There's just no getting around it: you're building a distributed

    system. -- Mark Cavage, ACM Queue Friday, November 22, 13
  2. Mobile & Desktop Apps Web Sites & Applications Internal APIs

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

    3rd-party Service APIs Public APIs fn(){} fn(){} fn(){} fn(){} fn(){} Friday, November 22, 13
  4. SDKs OK: Prototyping No good HTTP Client Building Clients Complex

    APIs Uses Native APIs Friday, November 22, 13
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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