Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

The Interaction Design Of APIs


Published on

Published in: Technology

The Interaction Design Of APIs

  1. The Interaction Design of APIs Stanford HCI Group Seminar on People, Computers, and Design April 17, 2009 Alex Payne API Lead, Twitter, Inc.
  2. Select Language ... What is Twitter? Watch a video! What? Why? How? Please sign in user name or email address: password: Sign In » Remember me Forgot password? Click here. Already using Twitter from Twitter is a service for friends, family, and co–workers your phone? Click here. to communicate and stay connected through the exchange of quick, frequent answers to one simple question: What are you doing? Get Started—Join! Suddenly, it seems as though When I first started doing it, I Incredibly useful all the world's a-twitter. thought, 'geez, not another website to worry about Wired updating and checking', but
  3. FrontPage Create a page EDIT VIEW Pages & Files Upload files Settings FrontPage Help last edited by Doug Williams 1 day ago Page history Search Pages and Files Welcome to the Twitter API wiki. What are you coding? Send a link Put this page in a different folder Documentation Frequently asked questions Add Tags REST API Documentation Page Security Search API Documentation REST API Changelog Migrating to followers terminology Navigator Official resources Official Resources REST API issue tracker - file bugs, request features FrontPage Request whitelisting Libraries @twitterapi - follow to get updates about the API Twitter API Announcements Google Group Migrating to followers terminology Moderators OAuth REST API Changelog OAuth FAQ OAuth Examples REST API Documentation Pages No Files Community Resources SideBar Twitter Development Talk Google Group
  4. Alex Payne writes online here. See also the archive, books & talks. The five most recent posts. Mending The Bitter Absence advertisement of Reasoned Technical Discussion There’s a counterpart to my post on technology journalism Delicious bookmarks on that I’ve been hesitant to write. Just as most professional your iPhone. Now journalism on high technology fails us today, so too does available in the App Store! the online discussion amongst technologists as a POWERED by FUSION community. Social media (blogs, community news sites like Reddit and Hacker News, Twitter and such) have swept in to fill a vacuum between peer-reviewed academic journals and water cooler conversation amongst software engineers. Anyone with a blog can publish development war stories, benchmarks, or an interview with another developer. It’s a world of engineer’s notebooks laid wide open, and in theory, we should be more informed as a profession than we ever have been. In practice, the conversations that are most widely heard in the tech community are full of inaccuracies, manufactured drama, ignorance, and unbridled opinion. In discussing these Internet-spanning debates with non- technical friends, comparisons to Hollywood tabloids come first to mind. It’s a time sink for an industry that should be a shining example of how to
  5. What’s an API?
  6. Why do we care about making good APIs?
  7. Why does this matter to an HCI person?
  8. The Twitter API 2 years old • 40 methods • 4,500+ registered developers • 5,000+ registered applications • multiple books (English, Japanese) • an even larger “invisible” ecosystem • hundreds of millions of requests per day •
  9. What do people build with the Twitter API?
  10. How does it feel?
  11. { quot;textquot;:quot;Kitty, don't boss me. I will feed you in due time.quot;, quot;truncatedquot;:false, quot;in_reply_to_status_idquot;:null, quot;in_reply_to_user_idquot;:null, quot;favoritedquot;:false, quot;in_reply_to_screen_namequot;:null, quot;idquot;:1516683992, quot;sourcequot;:quot;webquot;, quot;created_atquot;:quot;Tue Apr 14 13:47:41 +0000 2009quot;, quot;userquot;: { quot;statuses_countquot;:6426, quot;descriptionquot;:quot;No ideas but in things.quot;, quot;profile_background_tilequot;:false, quot;utc_osetquot;:-28800, quot;profile_text_colorquot;:quot;41446cquot;, quot;followingquot;:true, quot;profile_link_colorquot;:quot;ad102dquot;, quot;urlquot;:quot;http://blog.evanweaver.comquot;, quot;namequot;:quot;Evanquot;, quot;notificationsquot;:false, quot;profile_sidebar_fill_colorquot;:quot;quot;, quot;followers_countquot;:2308, quot;protectedquot;:false, quot;profile_background_image_urlquot;:quot; /6920721/BD2_1024-1.jpgquot;, quot;friends_countquot;:117, quot;profile_sidebar_border_colorquot;:quot;d5d4ecquot;, quot;time_zonequot;:quot;Pacific Time (US Canada)quot;, quot;profile_image_urlquot;:quot; BD2_1024_2-1_normal.jpgquot;, quot;favourites_countquot;:1032, quot;locationquot;:quot;Russian Hill, Californiaquot;, quot;idquot;:761613, quot;created_atquot;:quot;Fri Feb 09 22:59:00 +0000 2007quot;, quot;profile_background_colorquot;:quot;7b9ab7quot;, quot;screen_namequot;:quot;evanquot; } }
  12. What makes it easy? low barrier to entry: “just poke at it” • human-readable names • logical nesting of resources • predictable output • constrained set of object models •
  13. What frustrates developers? inconsistency • anything vague or unpredictable • lack of user interface conventions • network and performance issues •
  14. A shameful glimpse at bad APIs.
  15. import java.util.{Calendar, Date} lazy val updatedDate = { val rfc3339 = new SimpleDateFormat(quot;yyyy-MM-dd'T'h:m:ss'-05:00'quot;) val calendar = Calendar.getInstance calendar.set(year.toInt, month.toInt - 1, day.toInt) rfc3339.format(calendar.getTime) } java.util.Calendar, java.util.Date
  16. //Call SecKeychainAddGenericPassword to add a new password to the keychain: OSStatus StorePasswordKeychain (void* password,UInt32 passwordLength) { OSStatus status; status = SecKeychainAddGenericPassword ( NULL, // default keychain 10, // length of service name quot;SurfWriterquot;, // service name 10, // length of account name quot;MyUserAcctquot;, // account name passwordLength, // length of password password, // pointer to password data NULL // the item reference ); return (status); } //Call SecKeychainFindGenericPassword to get a password from the keychain: OSStatus GetPasswordKeychain (void *passwordData,UInt32 *passwordLength, SecKeychainItemRef *itemRef) { OSStatus status1 ; status1 = SecKeychainFindGenericPassword ( NULL, // default keychain 10, // length of service name quot;SurfWriterquot;, // service name 10, // length of account name quot;MyUserAcctquot;, // account name passwordLength, // length of password passwordData, // pointer to password data itemRef // the item reference ); return (status1); } //Call SecKeychainItemModifyAttributesAndData to change the password for // an item already in the keychain: OSStatus ChangePasswordKeychain (SecKeychainItemRef itemRef) { OSStatus status; void * password = quot;myNewP4sSw0rDquot;; UInt32 passwordLength = strlen(password); status = SecKeychainItemModifyAttributesAndData ( itemRef, // the item reference Keychain Services, Mac OS X NULL, // no change to attributes passwordLength, // length of password password // pointer to password data
  17. BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, case WM_COMMAND: WPARAM wParam, LPARAM lParam) switch(LOWORD(wParam)) { { switch(Message) case ID_HELP_ABOUT: { case WM_INITDIALOG: { int ret = DialogBox(GetModuleHandle(NULL), return TRUE; MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDlgProc); case WM_COMMAND: if(ret == IDOK){ switch(LOWORD(wParam)) MessageBox(hwnd, quot;Dialog exited with IDOK.quot;, quot;Noticequot;, { MB_OK | MB_ICONINFORMATION); case IDOK: } EndDialog(hwnd, IDOK); else if(ret == IDCANCEL){ break; MessageBox(hwnd, quot;Dialog exited with IDCANCEL.quot;, quot;Noticequot;, case IDCANCEL: MB_OK | MB_ICONINFORMATION); EndDialog(hwnd, IDCANCEL); } break; else if(ret == -1){ } MessageBox(hwnd, quot;Dialog failed!quot;, quot;Errorquot;, break; MB_OK | MB_ICONINFORMATION); default: } return FALSE; } } return TRUE; break; } // Other menu commands... } break; Win32
  18. {'message': {'code': 0, 'text': 'OK', 'version': '1.1.0'}, 'neighborhoods': [{'city': 'Berkeley', 'name': 'Gourmet Ghetto', 'borough': '', 'state': 'CA', 'state_code': 'CA', 'country': 'USA', 'country_code': 'US', 'url': '' }, {'city': 'Berkeley', 'name': 'North Berkeley', 'borough': '', 'state': 'CA', 'state_code': 'CA', 'country': 'USA', 'country_code': 'US', 'url': ''}] } Yelp
  19. A brief tour of excellent APIs.
  20. class CreateSavedSearches ActiveRecord::Migration def self.up create_table :saved_searches do |t| t.column :user_id, :integer t.column :name, :string t.column :query, :string t.column :position, :integer t.timestamps end add_index :saved_searches, :user_id end def self.down drop_table :saved_searches end end Rails Migrations
  21. $('form#login') .find('label.optional').hide().end() .find('input:password').css('border', '1px solid red').end() .submit(function() { return confirm('Are you sure you want to submit?'); }); jQuery
  22. import scala.actors.Actor._ val echoActor = actor { loop { receive { case msg = println(quot;received: quot; + msg) } } } echoActor ! quot;helloquot; echoActor ! quot;world!quot; Scala Actors
  23. What are the qualities of good APIs?
  24. Explorability.
  25. REST vs WS-* A case study in explorable APIs.
  26. Smalltalk Environment
  27. SLIME (the Superior Lisp Interaction Mode for Emacs)
  28. Predictability.
  29. ODBC, JDBC, etc. A case study in predictable APIs.
  30. Consistency.
  31. The options Hash in Rails A case study in consistent APIs.
  32. file_field(:post, :attached, :accept = 'text/html') file_field(:attachment, :file, :class = 'file_input') text_area(:post, :body, :cols = 20, :rows = 40) text_area(:comment, :text, :size = quot;20x30quot;) text_area(:entry, :body, :size = quot;20x20quot;, :disabled = 'disabled') submit_to_remote 'create_btn', 'Create', :url = { :action = 'create' } Rails Helpers
  33. The Humane API: explorable predictable consistent
  34. Thank you for listening. Questions?