Secrets of Awesome JavaScript API Design
Upcoming SlideShare
Loading in...5
×
 

Secrets of Awesome JavaScript API Design

on

  • 1,067 views

As developers, we know what good and bad JavaScript APIs "feel" like, and yet we struggle with designing the kind of APIs that we enjoy using. But principles of good JavaScript API design do exist, ...

As developers, we know what good and bad JavaScript APIs "feel" like, and yet we struggle with designing the kind of APIs that we enjoy using. But principles of good JavaScript API design do exist, and it's possible to extract them from several key libraries in the the proliferating JavaScript landscape. In this session, Brandon Satrom will do exactly that, digging into the design aspects of popular libraries like jQuery, Backbone, Knockout, Modernizer, Kendo UI and others to enumerate the designed-in qualities of these libraries that make them not only popular, but a pleasure to use.

Statistics

Views

Total Views
1,067
Views on SlideShare
1,067
Embed Views
0

Actions

Likes
1
Downloads
10
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NoDerivs LicenseCC Attribution-NoDerivs License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Secrets of Awesome JavaScript API Design Secrets of Awesome JavaScript API Design Presentation Transcript

    • Secrets of Awesome JavaScriptAPI DesignBrandon Satrom@BrandonSatrombrandon@KendoUI.com
    • Read it @bit.ly/ZS5VYv
    • 3Big Ideas
    • Three ideas...
    • Three ideas...1.APIs are “Developer UX”
    • Three ideas...1.APIs are “Developer UX”2.API Design is a universal practice
    • Three ideas...1.APIs are “Developer UX”2.API Design is a universal practice3.API Design is a “principle-driven” art form
    • What is design?
    • What is design?“form[ing] a plan or scheme of [something]… for later execution”- Oxford English Dictionary
    • Design is universal
    • We judge designs to be......elegant...beautiful...utilitarian...simple...or not...Images from: http://www.greatbuildings.com/ and http://list25.com/25-ugliest-buildings-in-the-world/
    • We judge designs to be......elegant...beautiful...utilitarian...simple...or not...Images from: http://www.greatbuildings.com/ and http://list25.com/25-ugliest-buildings-in-the-world/
    • We judge designs to be......elegant...beautiful...utilitarian...simple...or not...Images from: http://www.greatbuildings.com/ and http://list25.com/25-ugliest-buildings-in-the-world/
    • We judge designs to be......elegant...beautiful...utilitarian...simple...or not...Images from: http://www.greatbuildings.com/ and http://list25.com/25-ugliest-buildings-in-the-world/
    • “Mediocre design provably wastesthe world’s resources, corrupts theenvironment, affects internationalcompetitiveness. Design isimportant, teaching design isimportant.”- Fred BrooksImage of Fred Brooks from: http://en.wikipedia.org/wiki/File:Fred_Brooks.jpgPoor Design is Costly
    • We apply design practicesto User Interfaces...Images from: http://pinterest.com/fromupnorth/gui/
    • We call this practice,User Experience (UX)design...Images from: http://pinterest.com/fromupnorth/gui/
    • What about API Design?
    • API Design is “Developer UX”
    • API Design is not JUST ForLibrary Authors...
    • ...modular JS is written to beconsumed...
    • ...the number ofconsumers isirrelevant.Images from flickr.com/photos/powi/
    • In JavaScript, API design iscritically important...
    • Dynamic Language...
    • Anonymity ofconsumers...http://i.qkme.me/3qesq1.jpg
    • Ambiguity of Requirements...
    • Your users are smart...
    • Yeah, but myusers won’t...Image from: http://idratherbewriting.com/wp-content/uploads/2012/08/rtfmtractor.jpg
    • Yeah, but myusers won’t...Image from: http://idratherbewriting.com/wp-content/uploads/2012/08/rtfmtractor.jpg
    • A Tale of Ice &Water
    • A Tale of Ice &Water
    • A Tale of Ice &Water
    • A Tale of Ice &Water
    • A Tale of Ice &Water
    • In IndustrialDesign, this isNOT anacceptableanswer...Image from: http://idratherbewriting.com/wp-content/uploads/2012/08/rtfmtractor.jpg
    • ... how is Software Different?Image from: http://www.globalnerdy.com/wordpress/wp-content/uploads/2010/05/makeabetterfm.jpg
    • ... how is Software Different?Image from: http://www.globalnerdy.com/wordpress/wp-content/uploads/2010/05/makeabetterfm.jpgIt’s Not.
    • Your users are smart...
    • http://thebus.net/sites/default/files/americas-next-top-hipster.jpg
    • ...but they are NOT...you.http://thebus.net/sites/default/files/americas-next-top-hipster.jpg
    • Design the “pit of success”Image from: http://darrell.mozingo.net/2011/06/26/the-pit-of-success/
    • Example:$("article.blogPost").fadeIn();Use jQuery to select all article tags with the class “blogPost”
    • Example:$("article.blogPost").fadeIn();Use jQuery to select all article tags with the class “blogPost”article.blogPost  {    border-­‐radius:  10px;    background-­‐color:  salmon;    box-­‐shadow:  0px  0px  10px  2px  #ccc;}
    • Goals of API DesignBe Self-DescribingPrevent ErrorsMake Users FastImage from: http://elliottbrown.files.wordpress.com/2012/04/sandcastles.png
    • Goals are not enough...
    • ...we need guiding principles...
    • Principles, not Rules
    • Principles, not RulesRules are rote, often applied without contextPrinciples encourage application of context
    • Principles Found in Physical MediaImages from: http://char.txa.cornell.edu/language/principl/principl.htm & http://www.greatbuildings.com/
    • Principles on display in popularlibraries...BackbonejQueryKendo UIModernizrMoment.jsUnderscore
    • The Four PrinciplesUnity & HarmonyBalanceProportionEmphasis
    • WARNING! This is ART, notSCIENCE
    • Unity and HarmonyImage “Portrait of the children of Charles I” by Anthony Van Dyck from: http://char.txa.cornell.edu/language/principl/principl.htm
    • Unity andHarmony (art)Unity: The concept behind a work, or how the composer bringseverything together into a coherent whole.Harmony: The placement of similar elements throughout a work,yielding an uncomplicated and simple feel.Painting by Robert Delauny, from: http://char.txa.cornell.edu/language/principl/principl.htm
    • Unity & Harmony (API Design):Familiarity & ComfortExtended Object creation inBackboneWidget Instantiation inKendo UIUse similar and/orunifying elementsthrough your libraryto create familiarityand comfort
    • Example:Create Kendo UI Widgets from jQuery-selected DOM Elements$("ul.tree").kendoTreeView();$("ul.panel").kendoPanelBar();$("div").kendoGrid();
    • Example:Create Kendo UI Widgets from jQuery-selected DOM ElementsEach Widget is prefixedwith “kendo” and named ina consistent, camel-casedstyle$("ul.tree").kendoTreeView();$("ul.panel").kendoPanelBar();$("div").kendoGrid();
    • Example:Create Extended Objects with Backbonevar  Book  =  Backbone.Model.extend({    initialize:  function()  {  ...  },    author:  function()  {  ...  },    pubDate:  function()  {  ...  },});var  DocumentRow  =  Backbone.View.extend({    tagName:  "li",    className:  "row",    events:  {        "click  .icon":  "open",        "click  .button.edit":  "openEditDialog"    },    render:  function()  {  ...  }});
    • Example:Create Extended Objects with Backbone[Object].extend is used to“inherit” the built-infunctionality of BackboneModels, Views, Collectionsand Routersvar  Book  =  Backbone.Model.extend({    initialize:  function()  {  ...  },    author:  function()  {  ...  },    pubDate:  function()  {  ...  },});var  DocumentRow  =  Backbone.View.extend({    tagName:  "li",    className:  "row",    events:  {        "click  .icon":  "open",        "click  .button.edit":  "openEditDialog"    },    render:  function()  {  ...  }});
    • BalanceImage “Portrait of the children of Charles I” by Anthony Van Dyck from: http://char.txa.cornell.edu/language/principl/principl.htm
    • Balance (art)The arrangement of elements to ensure that no one part of the workoverpowers other parts, or causes it to feel unstable.Image of Italian Textile, 18th Centuty from: http://char.txa.cornell.edu/language/principl/principl.htm
    • Balance (API Design):Weight & PredictabilityBrowser Feature Tests inModernizrDOM Selection Syntax injQueryEnsure that eachfunction of yourlibrary exhibitsconsistent behavior,or aids in meeting acomplimentary goal.
    • Example:Modernizr.geolocationModernizr.localstorageModernizr.webworkersModernizr.canvasModernizr.borderradiusTest Browser Capabilities using Modernizr
    • Example:Modernizr.geolocationModernizr.localstorageModernizr.webworkersModernizr.canvasModernizr.borderradiusTest Browser Capabilities using ModernizrEach property matches anHTML5/CSS-related APIand returns a boolean
    • Example:$("#grid")  //  Selects  by  ID$("ul.nav  >  li")  //  All  LIs  for  UL  w/class  "nav"$("ul  li:nth-­‐child(2)")  //  2nd  item  in  each  listSelect DOM Elements using jQuery’s Selector Syntax
    • Example:$("#grid")  //  Selects  by  ID$("ul.nav  >  li")  //  All  LIs  for  UL  w/class  "nav"$("ul  li:nth-­‐child(2)")  //  2nd  item  in  each  listSelect DOM Elements using jQuery’s Selector SyntaxMany jQuery Selectorsmap directly to equivalentCSS selectors
    • ProportionImage “The Fisherman” by Saul Steinberg from: http://char.txa.cornell.edu/language/principl/principl.htm
    • Proportion (art)A measurement of the size and quantity of elements within a work,relative to the whole.Image of Salisbury Cathedral from: http://char.txa.cornell.edu/language/principl/principl.htm
    • Proportion (API Design):Scope that matches capabilityMoment.jsUnderscoreMake sure thatevery interface ofthe library matchesits intended purpose& that no extraneouselements exist.
    • Example:Moment.js is working working with dates... and that’s itmoment().format(dddd);moment().startOf(hour).fromNow();moment().format([Hello from] YYYY); // Hello from 2013moment().startOf(day).fromNow();
    • Example:Moment.js is working working with dates... and that’s itMoment is designed to make working with theJavaScript Date object tolerable, and it providesno functionality beyond that scope.moment().format(dddd);moment().startOf(hour).fromNow();moment().format([Hello from] YYYY); // Hello from 2013moment().startOf(day).fromNow();
    • _.each(["Todd",  "Burke",  "Derick"],  function(name){      alert(name);  });_.map([1,  2,  3],  function(num){      return  num  *  3;  });_.isNumber("ten");  //  FalseExample:Underscore.js, designed to add functional programming support to JS
    • _.each(["Todd",  "Burke",  "Derick"],  function(name){      alert(name);  });_.map([1,  2,  3],  function(num){      return  num  *  3;  });_.isNumber("ten");  //  FalseExample:Underscore.js, designed to add functional programming support to JSUnderscore provides utilityfunctions that help devs workwith JS collections, arrays,functions and objects. Larger APIsurface, for a broader purpose.
    • EmphasisImage of the FlatIron Building from: http://www.greatbuildings.com/
    • Emphasis (art)The point of focus or interruption of a work. The use of contrast tocause an aspect of the work to stand out and capture the viewer’sattention.Image from: http://char.txa.cornell.edu/language/principl/principl.htm
    • Emphasis (API Design):Creating a focal pointPlugin development usingjQuery’s fn namespaceMethod chaining in jQueryObject extensibility inBackboneProvide a gatewaymethod that anchorsyour library, a chainedor fluent API, or createextensibility hooks forconsuming devs
    • Example:jQuery enables a fluent programming style by returning ajQuery object from most functions.$(‘ul.first’).find(‘.overdue’)    .css(‘background-­‐color’,‘red’)    .end()    .find(‘.due-­‐soon’)    .css(‘background-­‐color’,  ‘yellow’);
    • Example:jQuery enables a fluent programming style by returning ajQuery object from most functions.This style enables devs to accomplish a greatdeal of work in a terse, yet readable manner.$(‘ul.first’).find(‘.overdue’)    .css(‘background-­‐color’,‘red’)    .end()    .find(‘.due-­‐soon’)    .css(‘background-­‐color’,  ‘yellow’);
    • (function($)  {    $.fn.kittehfy  =  function()  {        return  this.each(function(idx,  el)  {                            var  width  =  el.width,                height  =  el.height;            var  src=  "http://placekitten.com/";            el.src=  src  +  width  +  "/"  +  height;        });    };})(jQuery);$("img").kittehfy();Example:jQuery plugins are connected to jQuery via the fn (“effin”)namespace...
    • (function($)  {    $.fn.kittehfy  =  function()  {        return  this.each(function(idx,  el)  {                            var  width  =  el.width,                height  =  el.height;            var  src=  "http://placekitten.com/";            el.src=  src  +  width  +  "/"  +  height;        });    };})(jQuery);$("img").kittehfy();Example:jQuery plugins are connected to jQuery via the fn (“effin”)namespace...jQuery Plugins “feel” likenatural extensions tojQuery itself, and behavein similar ways
    • Example:    var  Book  =  Backbone.Model.extend({        initialize:  function()  {  ...  },    author:  function()  {  ...  },    pubDate:  function()  {  ...  },});var  DocumentRow  =  Backbone.View.extend({    tagName:  "li",    className:  "row",    events:  {        "click  .icon":  "open",        "click  .button.edit":  "openEditDialog"    },    render:  function()  {  ...  }});Create Extended Objects with Backbone
    • Example:    var  Book  =  Backbone.Model.extend({        initialize:  function()  {  ...  },    author:  function()  {  ...  },    pubDate:  function()  {  ...  },});var  DocumentRow  =  Backbone.View.extend({    tagName:  "li",    className:  "row",    events:  {        "click  .icon":  "open",        "click  .button.edit":  "openEditDialog"    },    render:  function()  {  ...  }});Create Extended Objects with Backbone[Object].extend is used to“inherit” the built-infunctionality of BackboneModels, Views, Collectionsand Routers
    • The Four PrinciplesUnity & HarmonyBalanceProportionEmphasis
    • The HORROR!aka What might go wrong...
    • What might go wrong...InconsistencyDisproportionality
    • Imbalance...Callback signatures on $.map, $.each & $(el).map
    • Imbalance...Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];$.each(letters,  function(index,  val)  {    console.log(index  +  “:  “  +  val.toUpperCase());Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];$.each(letters,  function(index,  val)  {    console.log(index  +  “:  “  +  val.toUpperCase());});  Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];$.each(letters,  function(index,  val)  {    console.log(index  +  “:  “  +  val.toUpperCase());});  Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];$.each(letters,  function(index,  val)  {    console.log(index  +  “:  “  +  val.toUpperCase());});  var  uppers  =  $.map(letters,  function(val,  index)  {    return  (val.toUpperCase());Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];$.each(letters,  function(index,  val)  {    console.log(index  +  “:  “  +  val.toUpperCase());});  var  uppers  =  $.map(letters,  function(val,  index)  {    return  (val.toUpperCase());});Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];$.each(letters,  function(index,  val)  {    console.log(index  +  “:  “  +  val.toUpperCase());});  var  uppers  =  $.map(letters,  function(val,  index)  {    return  (val.toUpperCase());});Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];$.each(letters,  function(index,  val)  {    console.log(index  +  “:  “  +  val.toUpperCase());});  var  uppers  =  $.map(letters,  function(val,  index)  {    return  (val.toUpperCase());});$(‘li’).map(function(index,  val)  {  //WAT  });Callback signatures on $.map, $.each & $(el).map
    • Imbalance...var  letters  =  [“a”,  “b”,  “c”,  “d”,  “e”];$.each(letters,  function(index,  val)  {    console.log(index  +  “:  “  +  val.toUpperCase());});  var  uppers  =  $.map(letters,  function(val,  index)  {    return  (val.toUpperCase());});$(‘li’).map(function(index,  val)  {  //WAT  });Callback signatures on $.map, $.each & $(el).mapNot only do $.map and $.each diverge, but $.map and $(el).map order thecallback params differently, depending on how the method is called.
    • Proportion: TooLarge or Too Small...
    • Image of Fred Brooks from: http://www-set.win.tue.nl/UnsungHeroes/files/PTERA-Kosten-Poel.jpg
    • Image of Fred Brooks from: http://www-set.win.tue.nl/UnsungHeroes/files/PTERA-Kosten-Poel.jpg“Van der Poel designed a computer with onlyone operation code...”
    • Image of Fred Brooks from: http://www-set.win.tue.nl/UnsungHeroes/files/PTERA-Kosten-Poel.jpg“... Every instruction carried out the sameoperation. He demonstrated the sufficiency ofhis operation—his machine could do anythingany other computer could do...”
    • Image of Fred Brooks from: http://www-set.win.tue.nl/UnsungHeroes/files/PTERA-Kosten-Poel.jpg“...And yet it was very difficult to program....”
    • Image of Fred Brooks from: http://www-set.win.tue.nl/UnsungHeroes/files/PTERA-Kosten-Poel.jpg“...the delight that came from using it wassimilar to... working out a crossword puzzle—a construct of intentional complexity and nointended utility.”- Fred Brooks
    • AwesomeLib.do(prams);
    • AwesomeLib.do(prams);We can all agreethat this is bad
    • jQuery();
    • jQuery();Then, so is this...
    • Overloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectOverloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapOverloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapjQuery(  object  )  //  WrapOverloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapjQuery(  object  )  //  WrapjQuery()  //  Empty  $  ObjectOverloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapjQuery(  object  )  //  WrapjQuery()  //  Empty  $  ObjectjQuery(  elementArray  )  //  WrapOverloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapjQuery(  object  )  //  WrapjQuery()  //  Empty  $  ObjectjQuery(  elementArray  )  //  WrapjQuery(    jQuery  object  )  //  CloneOverloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapjQuery(  object  )  //  WrapjQuery()  //  Empty  $  ObjectjQuery(  elementArray  )  //  WrapjQuery(    jQuery  object  )  //  ClonejQuery(  html  [,  ownerDocument  ]  )  //  Create  DOM  ElementsOverloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapjQuery(  object  )  //  WrapjQuery()  //  Empty  $  ObjectjQuery(  elementArray  )  //  WrapjQuery(    jQuery  object  )  //  ClonejQuery(  html  [,  ownerDocument  ]  )  //  Create  DOM  ElementsjQuery  (  html,  props  )  //  Create  DOM  ElementsOverloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapjQuery(  object  )  //  WrapjQuery()  //  Empty  $  ObjectjQuery(  elementArray  )  //  WrapjQuery(    jQuery  object  )  //  ClonejQuery(  html  [,  ownerDocument  ]  )  //  Create  DOM  ElementsjQuery  (  html,  props  )  //  Create  DOM  ElementsjQuery  (  callback  )  //  Bind  DOM  loaded  function  Overloads on the jQuery()method...
    • jQuery(  selector  [,  context]  )  //  SelectjQuery(  element  )  //  WrapjQuery(  object  )  //  WrapjQuery()  //  Empty  $  ObjectjQuery(  elementArray  )  //  WrapjQuery(    jQuery  object  )  //  ClonejQuery(  html  [,  ownerDocument  ]  )  //  Create  DOM  ElementsjQuery  (  html,  props  )  //  Create  DOM  ElementsjQuery  (  callback  )  //  Bind  DOM  loaded  function  Overloads on the jQuery()method...11 ways to calljQuery, with 6different contexts!
    • Now, for a question...
    • jQuery: GoodAPI Design orBad APIDesign?Image from: http://laughingsquid.com/wp-content/uploads/Kevin-Bacon.jpg
    • jQuery: GoodAPI Design orBad APIDesign?Image from: http://laughingsquid.com/wp-content/uploads/Kevin-Bacon.jpgA baseline example of “Good...”
    • jQuery: GoodAPI Design orBad APIDesign?Image from: http://laughingsquid.com/wp-content/uploads/Kevin-Bacon.jpgA baseline example of “Good...”
    • YES
    • Here’s thepoint...Image from: http://laughingsquid.com/wp-content/uploads/Kevin-Bacon.jpg
    • Building andevolving a usefulAPI is hard...Image from: http://www.ibiblio.org/xml/slides/xmlone/london2002/schemas/83.html
    • ...you won’t alwaysget it right.Image from: gorestruly.com2011/09/30/rotting-americana-the-winchester-mystery-house/
    • But hey, jQuery’s not perfect...
    • ... so you don’t have to be either.
    • Questions?@BrandonSatrombrandon@kendoui.com