Building ConsistentRESTful APIs in a High-Performance EnvironmentYegor Borovikov, Software ArchitectBrandon Duncan, Direct...
Topics We’ll Cover>   Examples of RESTful APIs       What’s missing?            Variety versus Uniformity>   Domain Mode...
Examples of RESTful APIsWhat if you want to get a person’s profile?>   Use one of these…    http://social.yahooapis.com/v1...
Examples of RESTful APIsWhat’s Missing?>   Ability to get exactly what you need (variety)       If you need more, may req...
Examples of RESTful APIsMultiple Calls to Get What You Need>   Want to get user’s friend’s profile? Do this…       http:/...
Examples of RESTful APIsMultiple Calls to Get What You Need>   … then make second call to get friend’s profile:    http://...
Typical SolutionVariety versus Uniformity>   Solution: introduce another call>   Desire for variety of responses    underm...
Domain Model as FoundationSample Domain Model/people : Person[]     //   collection of Person resources   /id : string    ...
Domain Model as FoundationFollow request URL to navigate through your model>   To get a person’s profile:    http://api.li...
Domain Model as FoundationFine-grained Request>   What if you only need certain fields    (e.g., name and photo)?    http:...
Domain Model as FoundationFine-grained Request>   To get names and photos of one’s friends and    their best friends:    …...
Domain Model as FoundationFine-grained Request>   Allows client to construct custom calls>   Better than digging for the c...
Domain Model as FoundationBenefits>   Provides a frame for both request and response    semantics>   Still allows for flex...
Examples of LinkedIn APIsHTTP GET - Read   …/people/email=brandon@gmail.com/friends?sort=name   …/people/123/friends;sort=...
Examples of LinkedIn APIsHTTP PUT - Update>   Set the user’s name:                           /people[/id=123]             ...
Examples of LinkedIn APIsHTTP POST - Create>   Add a friend                                              /people[/id=123] ...
Examples of LinkedIn APIsHTTP DELETE - Remove>   Remove a friendDELETE http://api.linkedin.com/v2/people/123/friends/456> ...
Use Standard Headers>   Content-Type>   Last-Modified>   Accept>   Vary>   Authorization>   Cache-Control>   Content-MD5> ...
Incentive System>   Multiple ways to get at the same data>   Partner can ask for exactly what they need>   Associate cost ...
Real-World ExampleXobni Toolbar>   Xobni makes ~20 million profile API calls per week>   Default representation is ~2k on ...
Yegor Borovikovyborovik@linkedin.comBrandon Duncanbduncan@linkedin.comblog.linkedin.com                        21
Upcoming SlideShare
Loading in …5
×

Javaone 2009 Building RESTful APIs

329 views

Published on

  • Be the first to comment

  • Be the first to like this

Javaone 2009 Building RESTful APIs

  1. 1. Building ConsistentRESTful APIs in a High-Performance EnvironmentYegor Borovikov, Software ArchitectBrandon Duncan, Director of EngineeringLinkedIn Corporationhttp://blog.linkedin.com/
  2. 2. Topics We’ll Cover> Examples of RESTful APIs  What’s missing?  Variety versus Uniformity> Domain Model as Foundation  Provides Uniformity  Allows Flexibility> Examples of LinkedIn APIs> Using Incentives to Scale  Some LinkedIn production APIs metrics> Q&A 2
  3. 3. Examples of RESTful APIsWhat if you want to get a person’s profile?> Use one of these… http://social.yahooapis.com/v1/user/{guid}/profile http://api.linkedin.com/v1/people/{guid} http://www.orkut.com/social/rest/people/{guid}/@self <?xml version="1.0" encoding="UTF-8"?> <person> <id>111222</id> <first-name>Gertrude</first-name> <last-name>Stein</last-name> <headline>Author of Tender Buttons</headline> <connections total="76"> … </person> 3
  4. 4. Examples of RESTful APIsWhat’s Missing?> Ability to get exactly what you need (variety)  If you need more, may require multiple API calls (if they exist)  If you need less, resources are wasted> Consistency of responses (uniformity)  “Same” object returned by different APIs may have different structure  Once in production, hard to get consistent later 4
  5. 5. Examples of RESTful APIsMultiple Calls to Get What You Need> Want to get user’s friend’s profile? Do this…  http://social.yahooapis.com/v1/user/123/connections<connections yahoo:start="0" yahoo:count="1" yahoo:total="1"> <connection yahoo:uri="http://social.yahooapis.com/v1/user/123/connection/456?view=usercard"> <guid>456</guid> <contactId>4</contactId> </connection></connections> 5
  6. 6. Examples of RESTful APIsMultiple Calls to Get What You Need> … then make second call to get friend’s profile: http://social.yahooapis.com/v1/user/456/profile <profile yahoo:uri="http://social.yahooapis.com/v1/user/456/profile"> <guid>456</guid> <birthdate>3/3</birthdate> <created>2008-08-4T17:13:56Z</created> ... </profile>  Latent, redundant data  Optimization requires stickiness 6
  7. 7. Typical SolutionVariety versus Uniformity> Solution: introduce another call> Desire for variety of responses undermines uniformity of requests> Leads to RPC-like REST APIs> Many APIs + Great Documentation = Lots of Reading + Lack of Automation 7
  8. 8. Domain Model as FoundationSample Domain Model/people : Person[] // collection of Person resources /id : string // primary key /name : string /email : string // unique key /photo : url /best-friend : Person /friends : Person[] /jobs : Job[] // collection of Job resources /company : Company /title : string /start-date : date /end-date : date …/companies : Company[] /name : string /ceo : Person … 8
  9. 9. Domain Model as FoundationFollow request URL to navigate through your model> To get a person’s profile: http://api.linkedin.com/v2/people/123 /people[/id=123] <person uri=“urn:linkedin:v2:people/123” key=“123”> /id <id>123</id> /name /email <name>Reid Hoffman</name> /photo <email>reid@linkedin.com</email> /best-friend <best-friend uri=“urn:linkedin:v2:people/456”/> /friends /jobs … /company </person> /title /start-date /end-date …  Conventional URL in request /companies /name  Default representation in response /ceo … 9
  10. 10. Domain Model as FoundationFine-grained Request> What if you only need certain fields (e.g., name and photo)? http://api.linkedin.com/v2/people/123:(name,photo) <person> <name>Reid Hoffman</name> /people[/id=123] <photo>http://media.linkedin.com/photos/123.jpeg</photo> /id /name </person> /email /photo /best-friend /friends /jobs /company /title /start-date /end-date … 10
  11. 11. Domain Model as FoundationFine-grained Request> To get names and photos of one’s friends and their best friends: …/v2/people/456/friends:(name,photo,best-friend: (name,photo)) /people[/id=456] /id <friends total=“66” start=“0”> /name /email <friend uri=“urn:linkedin:v2:people/123” key=“123”> /photo <name>Reid Hoffman</name> /best-friend <photo>http://media.linkedin.com/photos/123.jpeg</photo> /friends /123 <best-friend uri=“urn:linkedin:v2:people/456” key=“456”> /id <name>Brandon Duncan</name> /name /email <photo>http://media.linkedin.com/photos/456.jpeg</photo> /photo </best-friend> /best-friend </friend> /name /photo <friend>…</friend> /jobs </friends> … 11
  12. 12. Domain Model as FoundationFine-grained Request> Allows client to construct custom calls> Better than digging for the closest matching API: http://social...com/v1/user/123/profile http://social...com/v1/user/123/profile/usercard http://social...com/v1/user/123/profile/tinyusercard> Allows optimization on the backend 12
  13. 13. Domain Model as FoundationBenefits> Provides a frame for both request and response semantics> Still allows for flexible syntax  Requests – path, query params, matrix params…  Responses – JSON, XML, POJOs, protobuff…> Helps to unify and automate many development tasks on both ends  Request / response creation, parsing, marshalling  Code (and documentation) generation  Discovery services 13
  14. 14. Examples of LinkedIn APIsHTTP GET - Read …/people/email=brandon@gmail.com/friends?sort=name …/people/123/friends;sort=name:(name,jobs;sort=start-date) …/people:(id,name,photo)?name=page&company=google …/people::(123,456) …/people::(123,456):(name,photo) 14
  15. 15. Examples of LinkedIn APIsHTTP PUT - Update> Set the user’s name: /people[/id=123] /id /namePUT http://api.linkedin.com/v2/people/123/name /email<name>Reid Hoffmann</name> /photo /best-friend …> Update the user’s profile - change name and best- friend and remove photo:PUT http://api.linkedin.com/v2/people/123 /people[/id=123]<person> /id <name>Reid Hoffman</name> /name <best-friend uri=“urn:linkedin:v2:people/999”/> /email /photo <photo xsi:nil=“true”/> /best-friend</person> … 15
  16. 16. Examples of LinkedIn APIsHTTP POST - Create> Add a friend /people[/id=123] /idPOST http://api.linkedin.com/v2/people/123/friends /name /email<friend uri=“urn:linkedin:v2:people/888”/> /photo /best-friend201 Created /friends /456Location: http://api.linkedin.com/v2/people/123/friends/888 /888 … 16
  17. 17. Examples of LinkedIn APIsHTTP DELETE - Remove> Remove a friendDELETE http://api.linkedin.com/v2/people/123/friends/456> Delete a companyDELETE http://api.linkedin.com/v2/companies/exchange=NYSE&ticker=GM> Delete two companiesDELETE http://api.linkedin.com/v2/companies::(664,665) 17
  18. 18. Use Standard Headers> Content-Type> Last-Modified> Accept> Vary> Authorization> Cache-Control> Content-MD5> Location> Warning 18
  19. 19. Incentive System> Multiple ways to get at the same data> Partner can ask for exactly what they need> Associate cost with resources, system of accounting creates incentives for partners> Throttling by resource rather than API 19
  20. 20. Real-World ExampleXobni Toolbar> Xobni makes ~20 million profile API calls per week> Default representation is ~2k on average> Using in-line filter brings average to ~1.5k  25% reduction in response size  ~11000 Mbits savings per day  11k Mbits out of LinkedIn datacenter  11k Mbits into Xobni datacenter  Saves both companies money 20
  21. 21. Yegor Borovikovyborovik@linkedin.comBrandon Duncanbduncan@linkedin.comblog.linkedin.com 21

×