familugorg

how API

Oct 23rd, 2012
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 49.56 KB | None | 0 0
  1. Web API Design
  2. Crafting Interfaces that Developers Love
  3. Brian Mulloy
  4. Table of Contents
  5. Web API Design - Crafting Interfaces that Developers Love
  6. Introduction ............................................................................................................................................ 3
  7. Nouns are good; verbs are bad ......................................................................................................... 4
  8. Plural nouns and concrete names ................................................................................................... 8
  9. Simplify associations - sweep complexity under the ‘?’ ........................................................... 9
  10. Handling errors ................................................................................................................................... 10
  11. Tips for versioning.............................................................................................................................. 13
  12. Pagination and partial response.................................................................................................... 16
  13. What about responses that don’t involve resources? ............................................................ 19
  14. Supporting multiple formats .......................................................................................................... 20
  15. What about attribute names? ......................................................................................................... 21
  16. Tips for search...................................................................................................................................... 22
  17. Consolidate API requests in one subdomain ............................................................................. 23
  18. Tips for handling exceptional behavior ...................................................................................... 25
  19. Authentication...................................................................................................................................... 27
  20. Making requests on your API .......................................................................................................... 28
  21. Chatty APIs............................................................................................................................................. 30
  22. Complement with an SDK ................................................................................................................. 31
  23. The API Façade Pattern ..................................................................................................................... 32
  24. 2
  25. Web API Design - Crafting Interfaces that Developers Love
  26. Introduction
  27. If you’re reading this, chances are that you care about designing Web APIs that developers
  28. will love and that you’re interested in applying proven design principles and best practices
  29. to your Web API.
  30. One of the sources for our design thinking is REST. Because REST is an architectural style
  31. and not a strict standard, it allows for a lot of flexibly. Because of that flexibility and
  32. freedom of structure, there is also a big appetite for design best practices.
  33. This e-book is a collection of design practices that we have developed in collaboration with
  34. some of the leading API teams around the world, as they craft their API strategy through a
  35. design workshop that we provide at Apigee.
  36. We call our point of view in API design “pragmatic REST”, because it places the success of
  37. the developer over and above any other design principle. The developer is the customer for
  38. the Web API. The success of an API design is measured by how quickly developers can get
  39. up to speed and start enjoying success using your API.
  40. We’d love your feedback – whether you agree, disagree, or have some additional practices
  41. and tips to add. The API Craft Google Group is a place where Web API design enthusiasts
  42. come together to share and debate design practices – we’d love to see you there.
  43. Are you a Pragmatist or a RESTafarian?
  44. Let’s start with our overall point of view on API design. We advocate pragmatic, not
  45. dogmatic REST. What do we mean by dogmatic?
  46. You might have seen discussion threads on true REST - some of them can get pretty strict
  47. and wonky. Mike Schinkel sums it up well - defining a RESTafarian as follows:
  48. “A RESTifarian is a zealous proponent of the REST software architectural style as defined by
  49. Roy T. Fielding in Chapter 5 of his PhD. dissertation at UC Irvine. You can find RESTifarians in
  50. the wild on the REST-discuss mailing list. But be careful, RESTifarians can be extremely
  51. meticulous when discussing the finer points of REST ...”
  52. Our view: approach API design from the ‘outside-in’ perspective. This means we start by
  53. asking - what are we trying to achieve with an API?
  54. The API’s job is to make the developer as successful as possible. The orientation for APIs is
  55. to think about design choices from the application developer’s point of view.
  56. 3
  57. Web API Design - Crafting Interfaces that Developers Love
  58. Why? Look at the value chain below – the application developer is the lynchpin of the
  59. entire API strategy. The primary design principle when crafting your API should be to
  60. maximize developer productivity and success. This is what we call pragmatic REST.
  61. Pragmatic REST is a design problem
  62. You have to get the design right, because design communicates how something will be
  63. used. The question becomes - what is the design with optimal benefit for the app
  64. developer?
  65. The developer point of view is the guiding principle for all the specific tips and best
  66. practices we’ve compiled.
  67. Nouns are good; verbs are bad
  68. The number one principle in pragmatic RESTful design is: keep simple things simple.
  69. Keep your base URL simple and intuitive
  70. The base URL is the most important design affordance of your API. A simple and intuitive
  71. base URL design makes using your API easy.
  72. Affordance is a design property that communicates how something should be used without
  73. requiring documentation. A door handle's design should communicate whether you pull or
  74. push. Here's an example of a conflict between design affordance and documentation - not
  75. an intuitive interface!
  76. 4
  77. Web API Design - Crafting Interfaces that Developers Love
  78. A key litmus test we use for Web API design is that there should be only 2 base URLs per
  79. resource. Let's model an API around a simple object or resource, a dog, and create a Web
  80. API for it.
  81. The first URL is for a collection; the second is for a specific element in the collection.
  82. /dogs
  83. /dogs/1234
  84. Boiling it down to this level will also force the verbs out of your base URLs.
  85. Keep verbs out of your base URLs
  86. Many Web APIs start by using a method-driven approach to URL design. These method-
  87. based URLs sometimes contain verbs - sometimes at the beginning, sometimes at the end.
  88. For any resource that you model, like our dog, you can never consider one object in
  89. isolation. Rather, there are always related and interacting resources to account for - like
  90. owners, veterinarians, leashes, food, squirrels, and so on.
  91. 5
  92. Web API Design - Crafting Interfaces that Developers Love
  93. Think about the method calls required to address all the objects in the dogs’ world. The
  94. URLs for our resource might end up looking something like this.
  95. It's a slippery slope - soon you have a long list of URLs and no consistent pattern making it
  96. difficult for developers to learn how to use your API.
  97. Use HTTP verbs to operate on the collections and elements.
  98. For our dog resources, we have two base URLs that use nouns as labels, and we can operate
  99. on them with HTTP verbs. Our HTTP verbs are POST, GET, PUT, and DELETE. (We think of
  100. them as mapping to the acronym, CRUD (Create-Read-Update-Delete).)
  101. With our two resources (/dogs and /dogs/1234) and the four HTTP verbs, we have a
  102. rich set of capability that's intuitive to the developer. Here is a chart that shows what we
  103. mean for our dogs.
  104. 6
  105. Web API Design - Crafting Interfaces that Developers Love
  106. Resource
  107. /dogs
  108. /dogs/1234
  109. POST GET PUT DELETE
  110. create read update delete
  111. Error Show Bo If exists update Delete Bo
  112. Bo
  113. Create a new
  114. dog
  115. List dogs
  116. Bulk update
  117. dogs
  118. If not error
  119. Delete all dogs
  120. The point is that developers probably don't need the chart to understand how the API
  121. behaves. They can experiment with and learn the API without the documentation.
  122. In summary:
  123. Use two base URLs per resource.
  124. Keep verbs out of your base URLs.
  125. Use HTTP verbs to operate on the collections and elements.
  126. 7
  127. Web API Design - Crafting Interfaces that Developers Love
  128. Plural nouns and concrete names
  129. Let’s explore how to pick the nouns for your URLs.
  130. Should you choose singular or plural nouns for your resource names? You'll see popular
  131. APIs use both. Let's look at a few examples:
  132. Foursquare
  133. /checkins
  134. GroupOn
  135. /deals
  136. Zappos
  137. /Product
  138. Given that the first thing most people probably do with a RESTful API is a GET, we think it
  139. reads more easily and is more intuitive to use plural nouns. But above all, avoid a mixed
  140. model in which you use singular for some resources, plural for others. Being consistent
  141. allows developers to predict and guess the method calls as they learn to work with your
  142. API.
  143. Concrete names are better than abstract
  144. Achieving pure abstraction is sometimes a goal of API architects. However, that abstraction
  145. is not always meaningful for developers.
  146. Take for example an API that accesses content in various forms - blogs, videos, news
  147. articles, and so on.
  148. An API that models everything at the highest level of abstraction - as /items or /assets
  149. in our example - loses the opportunity to paint a tangible picture for developers to know
  150. what they can do with this API. It is more compelling and useful to see the resources listed
  151. as blogs, videos, and news articles.
  152. The level of abstraction depends on your scenario. You also want to expose a manageable
  153. number of resources. Aim for concrete naming and to keep the number of resources
  154. between 12 and 24.
  155. In summary, an intuitive API uses plural rather than singular nouns, and concrete rather
  156. than abstract names.
  157. 8
  158. Web API Design - Crafting Interfaces that Developers Love
  159. Simplify associations - sweep complexity under the ‘?’
  160. In this section, we explore API design considerations when handling associations between
  161. resources and parameters like states and attributes.
  162. Associations
  163. Resources almost always have relationships to other resources. What's a simple way to
  164. express these relationships in a Web API?
  165. Let's look again at the API we modeled in nouns are good, verbs are bad - the API that
  166. interacts with our dogs resource. Remember, we had two base URLs: /dogs and
  167. dogs/1234.
  168. We're using HTTP verbs to operate on the resources and collections. Our dogs belong to
  169. owners. To get all the dogs belonging to a specific owner, or to create a new dog for that
  170. owner, do a GET or a POST:
  171. GET /owners/5678/dogs
  172. Now, the relationships can be complex. Owners have relationships with veterinarians, who
  173. have relationships with dogs, who have relationships with food, and so on. It's not
  174. uncommon to see people string these together making a URL 5 or 6 levels deep. Remember
  175. that once you have the primary key for one level, you usually don't need to include the
  176. levels above because you've already got your specific object. In other words, you shouldn't
  177. need too many cases where a URL is deeper than what we have above
  178. /resource/identifier/resource.
  179. POST /owners/5678/dogs
  180. Sweep complexity behind the ‘?’
  181. Most APIs have intricacies beyond the base level of a resource. Complexities can include
  182. many states that can be updated, changed, queried, as well as the attributes associated with
  183. a resource.
  184. Make it simple for developers to use the base URL by putting optional states and attributes
  185. behind the HTTP question mark. To get all red dogs running in the park:
  186. In summary, keep your API intuitive by simplifying the associations between resources,
  187. and sweeping parameters and other complexities under the rug of the HTTP question
  188. mark.
  189. GET /dogs?color=red&state=running&location=park
  190. 9
  191. Web API Design - Crafting Interfaces that Developers Love
  192. Handling errors
  193. Many software developers, including myself, don't always like to think about exceptions
  194. and error handling but it is a very important piece of the puzzle for any software developer,
  195. and especially for API designers.
  196. Why is good error design especially important for API designers?
  197. From the perspective of the developer consuming your Web API, everything at the other
  198. side of that interface is a black box. Errors therefore become a key tool providing context
  199. and visibility into how to use an API.
  200. First, developers learn to write code through errors. The "test-first" concepts of the
  201. extreme programming model and the more recent "test driven development" models
  202. represent a body of best practices that have evolved because this is such an important and
  203. natural way for developers to work.
  204. Secondly, in addition to when they're developing their applications, developers depend on
  205. well-designed errors at the critical times when they are troubleshooting and resolving
  206. issues after the applications they've built using your API are in the hands of their users.
  207. How to think about errors in a pragmatic way with REST?
  208. Let's take a look at how three top APIs approach it.
  209. Facebook
  210. HTTP Status Code: 200
  211. {"type" : "OauthException", "message":"(#803) Some of the
  212. aliases you requested do not exist: foo.bar"}
  213. Twilio
  214. HTTP Status Code: 401
  215. {"status" : "401", "message":"Authenticate","code": 20003, "more
  216. info": "http://www.twilio.com/docs/errors/20003"}
  217. SimpleGeo
  218. HTTP Status Code: 401
  219. {"code" : 401, "message": "Authentication Required"}
  220. 10
  221. Web API Design - Crafting Interfaces that Developers Love
  222. Facebook
  223. No matter what happens on a Facebook request, you get back the 200-status code -
  224. everything is OK. Many error messages also push down into the HTTP response. Here they
  225. also throw an #803 error but with no information about what #803 is or how to react to it.
  226. Twilio
  227. Twilio does a great job aligning errors with HTTP status codes. Like Facebook, they provide
  228. a more granular error message but with a link that takes you to the documentation.
  229. Community commenting and discussion on the documentation helps to build a body of
  230. information and adds context for developers experiencing these errors.
  231. SimpleGeo
  232. SimpleGeo provides error codes but with no additional value in the payload.
  233. A couple of best practices
  234. Use HTTP status codes
  235. Use HTTP status codes and try to map them cleanly to relevant standard-based codes.
  236. There are over 70 HTTP status codes. However, most developers don't have all 70
  237. memorized. So if you choose status codes that are not very common you will force
  238. application developers away from building their apps and over to Wikipedia to figure out
  239. what you're trying to tell them.
  240. Therefore, most API providers use a small subset. For example, the Google GData API uses
  241. only 10 status codes; Netflix uses 9, and Digg, only 8.
  242. Google GData 400 401 403 404 409
  243. 200 201 304
  244. Digg 403 404 410 500 503
  245. 200 400
  246. Netflix
  247. 200 201
  248. 304
  249. 401
  250. 400
  251. 401
  252. 403
  253. 404
  254. 412
  255. 410
  256. 500
  257. How many status codes should you use for your API?
  258. 500
  259. When you boil it down, there are really only 3 outcomes in the interaction between an app
  260. and an API:
  261. 11
  262. Everything worked - success
  263. The application did something wrong – client error
  264. The API did something wrong – server error
  265. Web API Design - Crafting Interfaces that Developers Love
  266. Start by using the following 3 codes. If you need more, add them. But you shouldn't need to
  267. go beyond 8.
  268. 200 - OK
  269. 400 - Bad Request
  270. 500 - Internal Server Error
  271. If you're not comfortable reducing all your error conditions to these 3, try picking among
  272. these additional 5:
  273. 201 - Created
  274. 304 - Not Modified
  275. 404 – Not Found
  276. 401 - Unauthorized
  277. 403 - Forbidden
  278. (Check out this good Wikipedia entry for all HTTP Status codes.)
  279. It is important that the code that is returned can be consumed and acted upon by the
  280. application's business logic - for example, in an if-then-else, or a case statement.
  281. Make messages returned in the payload as verbose as possible.
  282. Code for code
  283. 200 – OK
  284. 401 – Unauthorized
  285. Message for people
  286. {"developerMessage" : "Verbose, plain language description of
  287. the problem for the app developer with hints about how to fix
  288. it.", "userMessage":"Pass this message on to the app user if
  289. needed.", "errorCode" : 12345, "more info":
  290. "http://dev.teachdogrest.com/errors/12345"}
  291. In summary, be verbose and use plain language descriptions. Add as many hints as your
  292. API team can think of about what's causing an error.
  293. We highly recommend you add a link in your description to more information, like Twilio
  294. does.
  295. 12
  296. Web API Design - Crafting Interfaces that Developers Love
  297. Tips for versioning
  298. Versioning is one of the most important considerations when designing your Web API.
  299. Never release an API without a version and make the version mandatory.
  300. Let's see how three top API providers handle versioning.
  301. Twilio
  302. salesforce.com
  303. Facebook
  304. /2010-04-01/Accounts/
  305. /services/data/v20.0/sobjects/Account
  306. ?v=1.0
  307. Twilio uses a timestamp in the URL (note the European format).
  308. At compilation time, the developer includes the timestamp of the application when the
  309. code was compiled. That timestamp goes in all the HTTP requests.
  310. When a request arrives, Twilio does a look up. Based on the timestamp they identify the
  311. API that was valid when this code was created and route accordingly.
  312. It's a very clever and interesting approach, although we think it is a bit complex. For
  313. example, it can be confusing to understand whether the timestamp is the compilation time
  314. or the timestamp when the API was released.
  315. Salesforce.com uses v20.0, placed somewhere in the middle of the URL.
  316. We like the use of the v. notation. However, we don't like using the .0 because it implies
  317. that the interface might be changing more frequently than it should. The logic behind an
  318. interface can change rapidly but the interface itself shouldn't change frequently.
  319. Facebook also uses the v. notation but makes the version an optional parameter.
  320. This is problematic because as soon as Facebook forced the API up to the next version, all
  321. the apps that didn't include the version number broke and had to be pulled back and
  322. version number added.
  323. 13
  324. Web API Design - Crafting Interfaces that Developers Love
  325. How to think about version numbers in a pragmatic way with REST?
  326. Never release an API without a version. Make the version mandatory.
  327. Specify the version with a 'v' prefix. Move it all the way to the left in the URL so that it has
  328. the highest scope (e.g. /v1/dogs).
  329. Use a simple ordinal number. Don't use the dot notation like v1.2 because it implies a
  330. granularity of versioning that doesn't work well with APIs--it's an interface not an
  331. implementation. Stick with v1, v2, and so on.
  332. How many versions should you maintain? Maintain at least one version back.
  333. For how long should you maintain a version? Give developers at least one cycle to react
  334. before obsoleting a version.
  335. Sometimes that's 6 months; sometimes it’s 2 years. It depends on your developers'
  336. development platform, application type, and application users. For example, mobile apps
  337. take longer to rev’ than Web apps.
  338. Should version and format be in URLs or headers?
  339. There is a strong school of thought about putting format and version in the header.
  340. Sometimes people are forced to put the version in the header because they have multiple
  341. inter-dependent APIs. That is often a symptom of a bigger problem, namely, they are
  342. usually exposing their internal mess instead of creating one, usable API facade on top.
  343. That’s not to say that putting the version in the header is a symptom of a problematic API
  344. design. It's not!
  345. In fact, using headers is more correct for many reasons: it leverages existing HTTP
  346. standards, it's intellectually consistent with Fielding's vision, it solves some hard real-
  347. world problems related to inter-dependent APIs, and more.
  348. However, we think the reason most of the popular APIs do not use it is because it's less fun
  349. to hack in a browser.
  350. Simple rules we follow:
  351. If it changes the logic you write to handle the response, put it in the URL so you can see it
  352. easily.
  353. If it doesn't change the logic for each response, like OAuth information, put it in the header.
  354. 14
  355. Web API Design - Crafting Interfaces that Developers Love
  356. These for example, all represent the same resource:
  357. dogs/1
  358. Content-Type: application/json
  359. dogs/1
  360. Content-Type: application/xml
  361. dogs/1
  362. Content-Type: application/png
  363. The code we would write to handle the responses would be very different.
  364. There's no question the header is more correct and it is still a very strong API design.
  365. 15
  366. Web API Design - Crafting Interfaces that Developers Love
  367. Pagination and partial response
  368. Partial response allows you to give developers just the information they need.
  369. Take for example a request for a tweet on the Twitter API. You'll get much more than a
  370. typical twitter app often needs - including the name of person, the text of the tweet, a
  371. timestamp, how often the message was re-tweeted, and a lot of metadata.
  372. Let's look at how several leading APIs handle giving developers just what they need in
  373. responses, including Google who pioneered the idea of partial response.
  374. LinkedIn
  375. This request on a person returns the ID, first name, last name, and the industry.
  376. /people:(id,first-name,last-name,industry)
  377. LinkedIn does partial selection using this terse :(...) syntax which isn't self-evident.
  378. Plus it's difficult for a developer to reverse engineer the meaning using a search engine.
  379. Facebook
  380. /joe.smith/friends?fields=id,name,picture
  381. Google
  382. Google and Facebook have a similar approach, which works well.
  383. ?fields=title,media:group(media:thumbnail)
  384. They each have an optional parameter called fields after which you put the names of fields
  385. you want to be returned.
  386. As you see in this example, you can also put sub-objects in responses to pull in other
  387. information from additional resources.
  388. Add optional fields in a comma-delimited list
  389. The Google approach works extremely well.
  390. Here's how to get just the information we need from our dogs API using this approach:
  391. It's simple to read; a developer can select just the information an app needs at a given time;
  392. it cuts down on bandwidth issues, which is important for mobile apps.
  393. /dogs?fields=name,color,location
  394. 16
  395. Web API Design - Crafting Interfaces that Developers Love
  396. The partial selection syntax can also be used to include associated resources cutting down
  397. on the number of requests needed to get the required information.
  398. Make it easy for developers to paginate objects in a database
  399. It's almost always a bad idea to return every resource in a database.
  400. Let's look at how Facebook, Twitter, and LinkedIn handle pagination. Facebook uses offset
  401. and limit. Twitter uses page and rpp (records per page). LinkedIn uses start and count
  402. Semantically, Facebook and LinkedIn do the same thing. That is, the LinkedIn start & count
  403. is used in the same way as the Facebook offset & limit.
  404. To get records 50 through 75 from each system, you would use:
  405. Facebook - offset 50 and limit 25
  406. Twitter - page 3 and rpp 25 (records per page)
  407. LinkedIn - start 50 and count 25
  408. Use limit and offset
  409. We recommend limit and offset. It is more common, well understood in leading databases,
  410. and easy for developers.
  411. /dogs?limit=25&offset=50
  412. Metadata
  413. We also suggest including metadata with each response that is paginated that indicated to
  414. the developer the total number of records available.
  415. What about defaults?
  416. My loose rule of thumb for default pagination is limit=10 with offset=0.
  417. (limit=10&offset=0)
  418. The pagination defaults are of course dependent on your data size. If your resources are
  419. large, you probably want to limit it to fewer than 10; if resources are small, it can make
  420. sense to choose a larger limit.
  421. 17
  422. Web API Design - Crafting Interfaces that Developers Love
  423. In summary:
  424. Support partial response by adding optional fields in a comma delimited list.
  425. Use limit and offset to make it easy for developers to paginate objects.
  426. 18
  427. Web API Design - Crafting Interfaces that Developers Love
  428. What about responses that don’t involve resources?
  429. API calls that send a response that's not a resource per se are not uncommon depending on
  430. the domain. We've seen it in financial services, Telco, and the automotive domain to some
  431. extent.
  432. Actions like the following are your clue that you might not be dealing with a "resource"
  433. response.
  434. Calculate
  435. Translate
  436. Convert
  437. For example, you want to make a simple algorithmic calculation like how much tax
  438. someone should pay, or do a natural language translation (one language in request;
  439. another in response), or convert one currency to another. None involve resources returned
  440. from a database.
  441. In these cases:
  442. Use verbs not nouns
  443. For example, an API to convert 100 euros to Chinese Yen:
  444. /convert?from=EUR&to=CNY&amount=100
  445. Make it clear in your API documentation that these “non-resource” scenarios are
  446. different.
  447. Simply separate out a section of documentation that makes it clear that you use verbs in
  448. cases like this – where some action is taken to generate or calculate the response, rather
  449. than returning a resource directly.
  450. 19
  451. Web API Design - Crafting Interfaces that Developers Love
  452. Supporting multiple formats
  453. We recommend that you support more than one format - that you push things out in one
  454. format and accept as many formats as necessary. You can usually automate the mapping
  455. from format to format.
  456. Here's what the syntax looks like for a few key APIs.
  457. Google Data
  458. ?alt=json
  459. Foursquare
  460. /venue.json
  461. Digg*
  462. Accept: application/json
  463. ?type=json
  464. * The type argument, if present, overrides the Accept header.
  465. Digg allows you to specify in two ways: in a pure RESTful way in the Accept header or in
  466. the type parameter in the URL. This can be confusing - at the very least you need to
  467. document what to do if there are conflicts.
  468. We recommend the Foursquare approach.
  469. To get the JSON format from a collection or specific element:
  470. dogs.json
  471. Developers and even casual users of any file system are familiar to this dot notation. It also
  472. requires just one additional character (the period) to get the point across.
  473. /dogs/1234.json
  474. What about default formats?
  475. In my opinion, JSON is winning out as the default format. JSON is the closest thing we have
  476. to universal language. Even if the back end is built in Ruby on Rails, PHP, Java, Python etc.,
  477. most projects probably touch JavaScript for the front-end. It also has the advantage of being
  478. terse - less verbose than XML.
  479. 20
  480. Web API Design - Crafting Interfaces that Developers Love
  481. What about attribute names?
  482. In the previous section, we talked about formats - supporting multiple formats and working
  483. with JSON as the default.
  484. This time, let's talk about what happens when a response comes back.
  485. You have an object with data attributes on it. How should you name the attributes?
  486. Here are API responses from a few leading APIs:
  487. Twitter
  488. "created_at": "Thu Nov 03 05:19;38 +0000 2011"
  489. Bing
  490. "DateTime": "2011-10-29T09:35:00Z"
  491. Foursquare
  492. "createdAt": 1320296464
  493. They each use a different code convention. Although the Twitter approach is familiar to me
  494. as a Ruby on Rails developer, we think that Foursquare has the best approach.
  495. How does the API response get back in the code? You parse the response (JSON parser);
  496. what comes back populates the Object. It looks like this
  497. If you chose the Twitter or Bing approach, your code looks like this. Its not JavaScript
  498. convention and looks weird - looks like the name of another object or class in the system,
  499. which is not correct.
  500. var myObject = JSON.parse(response);
  501. timing = myObject.created_at;
  502. timing - myObject.DateTime;
  503. Recommendations
  504. 21
  505. Use JSON as default
  506. Follow JavaScript conventions for naming attributes
  507. - Use medial capitalization (aka CamelCase)
  508. - Use uppercase or lowercase depending on type of object
  509. Web API Design - Crafting Interfaces that Developers Love
  510. This results in code that looks like the following, allowing the JavaScript developer to write
  511. it in a way that makes sense for JavaScript.
  512. "createdAt": 1320296464
  513. timing = myObject.createdAt;
  514. Tips for search
  515. While a simple search could be modeled as a resourceful API (for example,
  516. dogs/?q=red), a more complex search across multiple resources requires a different
  517. design.
  518. This will sound familiar if you've read the topic about using verbs not nouns when results
  519. don't return a resource from the database - rather the result is some action or calculation.
  520. If you want to do a global search across resources, we suggest you follow the Google model:
  521. Global search
  522. Here, search is the verb; ?q represents the query.
  523. /search?q=fluffy+fur
  524. Scoped search
  525. To add scope to your search, you can prepend with the scope of the search. For example,
  526. search in dogs owned by resource ID 5678
  527. Notice that we’ve dropped the explicit search in the URL and rely on the parameter ‘q’ to
  528. indicate the scoped query. (Big thanks to the contributors on the API Craft Google group for
  529. helping refine this approach.)
  530. /owners/5678/dogs?q=fluffy+fur
  531. Formatted results
  532. For search or for any of the action oriented (non-resource) responses, you can prepend
  533. with the format as follows:
  534. /search.xml?q=fluffy+fur
  535. 22
  536. Web API Design - Crafting Interfaces that Developers Love
  537. Consolidate API requests in one subdomain
  538. We’ve talked about things that come after the top-level domain. This time, let's explore
  539. stuff on the other side of the URL.
  540. Here's how Facebook, Foursquare, and Twitter handle this:
  541. Facebook provides two APIs. They started with api.facebook.com, then modified it to orient
  542. around the social graph graph.facebook.com.
  543. graph.facebook.com
  544. api.facebook.com
  545. Foursquare has one API.
  546. Twitter has three APIs; two of them focused on search and streaming.
  547. api.foursquare.com
  548. stream.twitter.com
  549. api.twitter.com
  550. search.twitter.com
  551. It's easy to understand how Facebook and Twitter ended up with more than one API. It has
  552. a lot to do with timing and acquisition, and it's easy to reconfigure a CName entry in your
  553. DNS to point requests to different clusters.
  554. But if we're making design decisions about what's in the best interest of app developer, we
  555. recommend following Foursquare's lead:
  556. Consolidate all API requests under one API subdomain.
  557. It's cleaner, easier and more intuitive for developers who you want to build cool apps using
  558. your API.
  559. Facebook, Foursquare, and Twitter also all have dedicated developer portals.
  560. developers.facebook.com
  561. developers.foursquare.com
  562. dev.twitter.com
  563. How to organize all of this?
  564. Your API gateway should be the top-level domain. For example, api.teachdogrest.com
  565. 23
  566. Web API Design - Crafting Interfaces that Developers Love
  567. In keeping with the spirit of REST, your developer portal should follow this pattern:
  568. developers.yourtopleveldomain. For example,
  569. developers.teachdogrest.com
  570. Do Web redirects
  571. Then optionally, if you can sense from requests coming in from the browser where the
  572. developer really needs to go, you can redirect.
  573. Say a developer types api.teachdogrest.com in the browser but there's no other
  574. information for the GET request, you can probably safely redirect to your developer portal
  575. and help get the developer where they really need to be.
  576. api developers (if from browser)
  577. dev  developers
  578. developer  developers
  579. 24
  580. Web API Design - Crafting Interfaces that Developers Love
  581. Tips for handling exceptional behavior
  582. So far, we've dealt with baseline, standard behaviors.
  583. Here we’ll explore some of the exceptions that can happen - when clients of Web APIs
  584. can't handle all the things we've discussed. For example, sometimes clients intercept HTTP
  585. error codes, or support limited HTTP methods.
  586. What are ways to handle these situations and work within the limitations of a specific
  587. client?
  588. When a client intercepts HTTP error codes
  589. One common thing in some versions of Adobe Flash - if you send an HTTP response that is
  590. anything other than HTTP 200 OK, the Flash container intercepts that response and puts
  591. the error code in front of the end user of the app.
  592. Therefore, the app developer doesn't have an opportunity to intercept the error code. App
  593. developers need the API to support this in some way.
  594. Twitter does an excellent job of handling this.
  595. They have an optional parameter suppress_response_codes. If
  596. suppress_response_codes is set to true, the HTTP response is always 200.
  597. /public_timelines.json?
  598. suppress_response_codes=true
  599. HTTP status code: 200 {"error":"Could not authenticate you."}
  600. Notice that this parameter is a big verbose response code. (They could have used
  601. something like src, but they opted to be verbose.)
  602. This is important because when you look at the URL, you need to see that the response
  603. codes are being suppressed as it has huge implications about how apps are going to
  604. respond to it.
  605. Overall recommendations:
  606. 1 - Use suppress_response_codes = true
  607. 2 - The HTTP code is no longer just for the code
  608. The rules from our previous Handling Errors section change. In this context, the HTTP code
  609. is no longer just for the code - the program - it's now to be ignored. Client apps are never
  610. going to be checking the HTTP status code, as it is always the same.
  611. 25
  612. Web API Design - Crafting Interfaces that Developers Love
  613. 3 - Push any response code that we would have put in the HTTP response down into the
  614. response message
  615. In my example below, the response code is 401. You can see it in the response message.
  616. Also include additional error codes and verbose information in that message.
  617. Always return OK
  618. /dogs?suppress_response_codes = true
  619. Code for ignoring
  620. 200 - OK
  621. Message for people & code
  622. {response_code" : 401, "message" : "Verbose, plain language
  623. description of the problem with hints about how to fix it."
  624. "more_info" : "http://dev.tecachdogrest.com/errors/12345",
  625. "code" : 12345}
  626. When a client supports limited HTTP methods
  627. It is common to see support for GET and POST and not PUT and DELETE.
  628. To maintain the integrity of the four HTTP methods, we suggest you use the following
  629. methodology commonly used by Ruby on Rails developers:
  630. Make the method an optional parameter in the URL.
  631. Then the HTTP verb is always a GET but the developer can express rich HTTP verbs and
  632. still maintain a RESTful clean API.
  633. Create
  634. /dogs?method=post
  635. Read
  636. /dogs
  637. Update
  638. /dogs/1234?method=put&location=park
  639. Delete
  640. /dogs/1234?method=delete
  641. WARNING: It can be dangerous to provide post or delete capabilities using a GET method
  642. because if the URL is in a Web page then a Web crawler like the Googlebot can create or
  643. destroy lots of content inadvertently. Be sure you understand the implications of supporting
  644. this approach for your applications' context.
  645. 26
  646. Web API Design - Crafting Interfaces that Developers Love
  647. Authentication
  648. There are many schools of thought. My colleagues at Apigee and I don't always agree on
  649. how to handle authentication - but overall here's my take.
  650. Let's look at these three top services. See how each of these services handles things
  651. differently:
  652. PayPal
  653. Permissions Service API
  654. Facebook
  655. OAuth 2.0
  656. Twitter
  657. OAuth 1.0a
  658. Note that PayPal's proprietary three-legged permissions API was in place long before
  659. OAuth was conceived.
  660. What should you do?
  661. Use the latest and greatest OAuth - OAuth 2.0 (as of this writing). It means that Web or
  662. mobile apps that expose APIs don’t have to share passwords. It allows the API provider to
  663. revoke tokens for an individual user, for an entire app, without requiring the user to
  664. change their original password. This is critical if a mobile device is compromised or if a
  665. rogue app is discovered.
  666. Above all, OAuth 2.0 will mean improved security and better end-user and consumer
  667. experiences with Web and mobile apps.
  668. Don't do something *like* OAuth, but different. It will be frustrating for app developers if
  669. they can't use an OAuth library in their language because of your variation.
  670. 27
  671. Web API Design - Crafting Interfaces that Developers Love
  672. Making requests on your API
  673. Lets take a look at what some API requests and responses look like for our dogs API.
  674. Create a brown dog named Al
  675. POST /dogs
  676. name=Al&furColor=brown
  677. Response
  678. 200 OK
  679. {
  680. "dog":{
  681. "id": "1234",
  682. "name": "Al",
  683. "furColor": "brown"
  684. }
  685. }
  686. Rename Al to Rover - Update
  687. PUT /dogs/1234
  688. name=Rover
  689. Response
  690. 200 OK
  691. {
  692. "dog":{
  693. "id":"1234",
  694. "name": "Rover",
  695. "furColor": "brown"
  696. }
  697. }
  698. 28
  699. Web API Design - Crafting Interfaces that Developers Love
  700. Tell me about a particular dog
  701. GET /dogs/1234
  702. Response
  703. 200 OK
  704. {
  705. "dog":{
  706. "id":"1234",
  707. "name": "Rover",
  708. "furColor": "brown"
  709. }
  710. }
  711. Tell me about all the dogs
  712. GET /dogs
  713. Response
  714. 200 OK
  715. {
  716. "dogs":
  717. [{"dog":{
  718. "id":"1233",
  719. "name": "Fido",
  720. "furColor": "white"}},
  721. {"dog":{
  722. "id":"1234",
  723. "name": "Rover",
  724. "furColor": "brown"}}]
  725. "_metadata":
  726. [{"totalCount":327,"limit":25,"offset":100}]
  727. }
  728. Delete Rover :-(
  729. DELETE /dogs/1234
  730. Response
  731. 200 OK
  732. 29
  733. Web API Design - Crafting Interfaces that Developers Love
  734. Chatty APIs
  735. Let’s think about how app developers use that API you're designing and dealing with chatty
  736. APIs.
  737. Imagine how developers will use your API
  738. When designing your API and resources, try to imagine how developers will use it to say
  739. construct a user interface, an iPhone app, or many other apps.
  740. Some API designs become very chatty - meaning just to build a simple UI or app, you have
  741. dozens or hundreds of API calls back to the server.
  742. The API team can sometimes decide not to deal with creating a nice, resource-oriented
  743. RESTful API, and just fall back to a mode where they create the 3 or 4 Java-style getter and
  744. setter methods they know they need to power a particular user interface.
  745. We don't recommend this. You can design a RESTful API and still mitigate the chattiness.
  746. Be complete and RESTful and provide shortcuts
  747. First design your API and its resources according to pragmatic RESTful design principles
  748. and then provide shortcuts.
  749. What kind of shortcut? Say you know that 80% of all your apps are going to need some sort
  750. of composite response, then build the kind of request that gives them what they need.
  751. Just don't do the latter instead of the former. First design using good pragmatic RESTful
  752. principles!
  753. Take advantage of the partial response syntax
  754. The partial response syntax discussed in a previous section can help.
  755. To avoid creating one-off base URLs, you can use the partial response syntax to drill down
  756. to dependent and associated resources.
  757. In the case of our dogs API, the dogs have association with owners, who in turn have
  758. associations with veterinarians, and so on. Keep nesting the partial response syntax using
  759. dot notation to get back just the information you need.
  760. /owners/5678?fields=name,dogs.name
  761. 30
  762. Web API Design - Crafting Interfaces that Developers Love
  763. Complement with an SDK
  764. It’s a common question for API providers - do you need to complement your API with code
  765. libraries and software development kits (SDKs)?
  766. If your API follows good design practices, is self consistent, standards-based, and well
  767. documented, developers may be able to get rolling without a client SDK. Well-documented
  768. code samples are also a critical resource.
  769. On the other hand, what about the scenario in which building a UI requires a lot of domain
  770. knowledge? This can be a challenging problem for developers even when building UI and
  771. apps on top of APIs with pretty simple domains – think about the Twitter API with it’s
  772. primary object of 140 characters of text.
  773. You shouldn't change your API to try to overcome the domain knowledge hurdle. Instead,
  774. you can complement your API with code libraries and a software development kit (SDK).
  775. In this way, you don't overburden your API design. Often, a lot of what's needed is on the
  776. client side and you can push that burden to an SDK.
  777. The SDK can provide the platform-specific code, which developers use in their apps to
  778. invoke API operations - meaning you keep your API clean.
  779. Other reasons you might consider complementing your API with an SDK include the
  780. following:
  781. Speed adoption on a specific platform. (For example Objective C SDK for iPhone.)
  782. Many experienced developers are just starting off with objective C+ so an SDK might be
  783. helpful.
  784. Simplify integration effort required to work with your API - If key use cases are
  785. complex or need to be complemented by standard on-client processing.
  786. An SDK can help reduce bad or inefficient code that might slow down service for
  787. everyone.
  788. As a developer resource - good SDKs are a forcing function to create good source code
  789. examples and documentation. Yahoo! and Paypal are good examples:
  790. Yahoo! http://developer.yahoo.com/social/sdk/
  791. Paypal https://cms.paypal.com/us/cgi-bin/?cmd=_render-
  792. content&content_ID=developer/library_download_sdks
  793. To market your API to a specific community - you upload the SDK to a samples or plug-
  794. in page on a platform’s existing developer community.
  795. 31
  796. Web API Design - Crafting Interfaces that Developers Love
  797. The API Façade Pattern
  798. At this point, you may be asking -
  799. What should we be thinking from an architectural perspective?
  800. How do we follow all these best practice guidelines, expose my internal services and systems in
  801. a way that’s useful to app developers, and still iterate and maintain my API?
  802. Back-end systems of record are often too complex to expose directly to application
  803. developers. They are stable (have been hardened over time) and dependable (they are
  804. running key aspects of you business), but they are often based on legacy technologies and
  805. not always easy to expose to Web standards like HTTP. These systems can also have
  806. complex interdependencies and they change slowly meaning that they can’t move as
  807. quickly as the needs of mobile app developers and keep up with changing formats.
  808. In fact, the problem is not creating an API for just one big system but creating an API for an
  809. array of complementary systems that all need to be used to make an API valuable to a
  810. developer.
  811. Big
  812. system
  813. DB
  814. Content
  815. Mgmt
  816. SOAP
  817. JDBC
  818. RSS
  819. It’s useful to talk through a few anti-patterns that we’ve seen. Let’s look at why we believe
  820. they don’t work well.
  821. The Build Up Approach
  822. In the build-up approach, a developer exposes the core objects of a big system and puts an
  823. XML parsing layer on top.
  824. XML
  825. Expose Objects
  826. Big System
  827. 32
  828. Web API Design - Crafting Interfaces that Developers Love
  829. This approach has merit in that it can get you to market with version 1 quickly. Also, your
  830. API team members (your internal developers) already understand the details of the
  831. system.
  832. Unfortunately, those details of an internal system at the object level are fine grained and
  833. can be confusing to external developers. You’re also exposing details of internal
  834. architecture, which is rarely a good idea. This approach can be inflexible because you have
  835. 1:1 mapping to how a system works and how it is exposed to API. In short, building up
  836. from the systems of record to the API can be overly complicated.
  837. The Standards Committee Approach
  838. Often the internal systems are owned and managed by different people and departments
  839. with different views about how things should work. Designing an API by a standards
  840. committee often involves creating a standards document, which defines the schema and
  841. URLs and such. All the stakeholders build toward that common goal.
  842. Standards
  843. Doc
  844. XML
  845. Expose
  846. Big System
  847. XML
  848. Expose
  849. DB
  850. XML
  851. Expose RSS
  852. Content
  853. Mgmt
  854. The benefits of this approach include getting to version 1 quickly. You can also create a
  855. sense of unification across an organization and a comprehensive strategy, which can be
  856. significant accomplishments when you have a large organization with a number of
  857. stakeholders and contributors.
  858. A drawback of the standards committee pattern is that it can be slow. Even if you get the
  859. document created quickly, getting everybody to implement against it can be slow and can
  860. lack adherence. This approach can also lead to a mediocre design as a result of too many
  861. compromises.
  862. 33
  863. Web API Design - Crafting Interfaces that Developers Love
  864. The Copy Cat Approach
  865. We sometimes see this pattern when an organization is late to market – for example, when
  866. their close competitor has already delivered a solution. Again, this approach can get you to
  867. version 1 quickly and you may have a built-in adoption curve if the app developers who
  868. will use your API are already familiar with your competitor’s API.
  869. Competitor’s
  870. API Doc
  871. XML
  872. Expose
  873. Big System
  874. XML
  875. Expose
  876. DB
  877. XML
  878. Expose RSS
  879. Content
  880. Mgmt
  881. However, you can end up with an undifferentiated product that is considered an inferior
  882. offering in the market of APIs. You might have missed exposing your own key value and
  883. differentiation by just copying someone else’s API design.
  884. Solution – The API façade pattern
  885. The best solution starts with thinking about the fundamentals of product management.
  886. Your product (your API) needs to be credible, relevant, and differentiated. Your product
  887. manager is a key member of your API team
  888. Once your product manager has decided what the big picture is like, it’s up to the
  889. architects.
  890. We recommend you implement an API façade pattern. This pattern gives you a buffer or
  891. virtual layer between the interface on top and the API implementation on the bottom. You
  892. essentially create a façade – a comprehensive view of what the API should be and
  893. importantly from the perspective of the app developer and end user of the apps they
  894. create.
  895. 34
  896. Web API Design - Crafting Interfaces that Developers Love
  897. Big
  898. System
  899. DB
  900. API Facade
  901. Content
  902. Mgmt
  903. SOAP
  904. JDB
  905. C
  906. RSS
  907. The developer and the app that consume the API are on top. The API façade isolates the
  908. developer and the application and the API. Making a clean design in the facade allows you
  909. to decompose one really hard problem into a few simpler problems.
  910. “Use the façade pattern when you want to provide a simple interface to a complex subsystem.
  911. Subsystems often get more complex as they evolve.”
  912. Design Patterns – Elements of Reusable Object-Oriented Software
  913. (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides)
  914. Implementing an API façade pattern involves three basic steps.
  915. 1 - Design the ideal API – design the URLs, request parameters and responses, payloads,
  916. headers, query parameters, and so on. The API design should be self-consistent.
  917. 2 - Implement the design with data stubs. This allows application developers to use your
  918. API and give you feedback even before your API is connected to internal systems.
  919. 3 - Mediate or integrate between the façade and the systems.
  920. 35
  921. Web API Design - Crafting Interfaces that Developers Love
  922. Ideal Design
  923. Big
  924. System
  925. DB
  926. API Facade
  927. Mediate
  928. Content
  929. Mgmt
  930. SOAP
  931. JDBC
  932. RSS
  933. Using the three-step approach you’ve decomposed one big problem to three smaller
  934. problems. If you try to solve the one big problem, you’ll be starting in code, and trying to
  935. build up from your business logic (systems of record) to a clean API interface. You would
  936. be exposing objects or tables or RSS feeds from each silo, mapping each to XML in the right
  937. format before exposing to the app. It is a machine–to-machine orientation focused around
  938. an app and is difficult to get this right.
  939. Taking the façade pattern approach helps shift the thinking from a silo approach in a
  940. number of important ways. First, you can get buy in around each of the three separate
  941. steps and have people more clearly understand how you’re taking a pragmatic approach to
  942. the design. Secondly, the orientation shifts from the app to the app developer. The goal
  943. becomes to ensure that the app developer can use your API because the design is self-
  944. consistent and intuitive.
  945. Because of where it is in the architecture, the façade becomes an interesting gateway. You
  946. can now have the façade implement the handling of common patterns (for pagination,
  947. queries, ordering, sorting, etc.), authentication, authorization, versioning, and so on,
  948. uniformly across the API. (This is a big topic and a full discussion is beyond the scope of
  949. this article.)
  950. Other benefits for the API team include being more easily able to adapt to different use
  951. cases regardless of whether they are internal developer, partner, or open scenarios. The
  952. API team will be able to keep pace with the changing needs of developers, including the
  953. ever-changing protocols and languages. It is also easier to extend an API by building out
  954. more capability from your enterprise or plugging in additional existing systems.
  955. 36
  956. Web API Design - Crafting Interfaces that Developers Love
  957. Resources
  958. Representational State Transfer (REST), Roy Thomas Fielding, 2000
  959. RESTful API Design Webinar, 2nd edition, Brian Mulloy, 2011
  960. Apigee API Tech & Best Practices Blog
  961. API Craft Google Group
  962. About Brian Mulloy
  963. Brian Mulloy, Apigee
  964. Brian has 15 years of experience ranging from enterprise software to founding a Web
  965. startup. He co-founded and was CEO of Swivel, a Website for social data analysis. He was
  966. President and General Manager of Grand Central, a cloud-based offering for application
  967. infrastructure (before we called it the cloud). And was Director of Product Marketing at
  968. BEA Systems. Brian holds a degree in Physics from the University of Michigan.
  969. Brian is a frequent contributor on the Apigee API Tech & best practices blog, the Apigee
  970. YouTube channel, the API Craft Google Group, and Webinars.
  971. About Apigee
  972. Apigee is the leading provider of API products and technology for enterprises and
  973. developers. Hundreds of enterprises like Comcast, GameSpy, TransUnion
  974. Interactive, Guardian Life and Constant Contact and thousands of developers use
  975. Apigee's technology. Enterprises use Apigee for visibility, control and scale of their
  976. API strategies. Developers use Apigee to learn, explore and develop API-based
  977. applications. Learn more at http://apigee.com.
  978. Accelerate your API Strategy
  979. Scale Control and Secure your Enterprise
  980. Developers – Consoles for the APIs you
Advertisement
Add Comment
Please, Sign In to add comment