SlideShare ist ein Scribd-Unternehmen logo
1 von 21
Building Consistent
RESTful APIs in a High-
Performance Environment
Yegor Borovikov, Software Architect
Brandon Duncan, Director of Engineering
LinkedIn Corporation
http://blog.linkedin.com/
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
Examples of RESTful APIs
What 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
Examples of RESTful APIs
What’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
Examples of RESTful APIs
Multiple 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
Examples of RESTful APIs
Multiple 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
Typical Solution
Variety 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
Domain Model as Foundation
Sample 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
Domain Model as Foundation
Follow 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
Domain Model as Foundation
Fine-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
Domain Model as Foundation
Fine-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
Domain Model as Foundation
Fine-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
Domain Model as Foundation
Benefits
>   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
Examples of LinkedIn APIs
HTTP 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
Examples of LinkedIn APIs
HTTP PUT - Update
>   Set the user’s name:                           /people[/id=123]
                                                      /id
                                                      /name
PUT 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
Examples of LinkedIn APIs
HTTP POST - Create
>   Add a friend                                              /people[/id=123]
                                                                 /id
POST http://api.linkedin.com/v2/people/123/friends               /name
                                                                 /email
<friend uri=“urn:linkedin:v2:people/888”/>                       /photo
                                                                 /best-friend
201 Created                                                      /friends
                                                                   /456
Location: http://api.linkedin.com/v2/people/123/friends/888        /888
                                                                 …




                                                                                 16
Examples of LinkedIn APIs
HTTP DELETE - Remove
>   Remove a friend
DELETE http://api.linkedin.com/v2/people/123/friends/456

>   Delete a company
DELETE
  http://api.linkedin.com/v2/companies/exchange=NYSE&ticker=GM

>   Delete two companies
DELETE http://api.linkedin.com/v2/companies::(664,665)




                                                                 17
Use Standard Headers

>   Content-Type
>   Last-Modified
>   Accept
>   Vary
>   Authorization
>   Cache-Control
>   Content-MD5
>   Location
>   Warning

                       18
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
Real-World Example
Xobni 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
Yegor Borovikov
yborovik@linkedin.com
Brandon Duncan
bduncan@linkedin.com
blog.linkedin.com


                        21

Weitere ähnliche Inhalte

Ähnlich wie Javaone 2009 Building RESTful APIs

MTC 2013 Berlin - Best Practices for Multi Devices
MTC 2013 Berlin - Best Practices for Multi DevicesMTC 2013 Berlin - Best Practices for Multi Devices
MTC 2013 Berlin - Best Practices for Multi DevicesHasan Hosgel
 
Microdata semantic-extend
Microdata semantic-extendMicrodata semantic-extend
Microdata semantic-extendSeek Tan
 
WordPress Tips and Tricks (DFW Meetup)
WordPress Tips and Tricks (DFW Meetup)WordPress Tips and Tricks (DFW Meetup)
WordPress Tips and Tricks (DFW Meetup)Stephanie Leary
 
Advanced Structured Data: Beyond Rich Snippets
Advanced Structured Data: Beyond Rich SnippetsAdvanced Structured Data: Beyond Rich Snippets
Advanced Structured Data: Beyond Rich SnippetsJustin Briggs
 
[2019] HTTP API 설계 후회 고민
[2019] HTTP API 설계 후회 고민[2019] HTTP API 설계 후회 고민
[2019] HTTP API 설계 후회 고민NHN FORWARD
 
Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?Fabio Kung
 
Proposed schema changes - have your say
Proposed schema changes - have your sayProposed schema changes - have your say
Proposed schema changes - have your sayCrossref
 
Building Windows 8 Apps with Windows Azure
Building Windows 8 Apps with Windows AzureBuilding Windows 8 Apps with Windows Azure
Building Windows 8 Apps with Windows AzureSupote Phunsakul
 
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...Codemotion
 
Associations & JavaScript
Associations & JavaScriptAssociations & JavaScript
Associations & JavaScriptJoost Elfering
 
FamilySearch Reference Client
FamilySearch Reference ClientFamilySearch Reference Client
FamilySearch Reference ClientDallan Quass
 
Gem christmas calendar
Gem christmas calendarGem christmas calendar
Gem christmas calendarerichsen
 
Creating HTML Pages
Creating HTML PagesCreating HTML Pages
Creating HTML PagesMike Crabb
 
WordPress Hidden Gems (July 2011)
WordPress Hidden Gems (July 2011)WordPress Hidden Gems (July 2011)
WordPress Hidden Gems (July 2011)Stephanie Leary
 
Copy of-a-walk-around-westfall-plaza
Copy of-a-walk-around-westfall-plazaCopy of-a-walk-around-westfall-plaza
Copy of-a-walk-around-westfall-plazahelgawerth
 
User Profiles: I Didn't Know I Could Do That? (Demo Slides)
User Profiles:  I Didn't Know I Could Do That?  (Demo Slides)User Profiles:  I Didn't Know I Could Do That?  (Demo Slides)
User Profiles: I Didn't Know I Could Do That? (Demo Slides)Stacy Deere
 

Ähnlich wie Javaone 2009 Building RESTful APIs (20)

MTC 2013 Berlin - Best Practices for Multi Devices
MTC 2013 Berlin - Best Practices for Multi DevicesMTC 2013 Berlin - Best Practices for Multi Devices
MTC 2013 Berlin - Best Practices for Multi Devices
 
Microdata semantic-extend
Microdata semantic-extendMicrodata semantic-extend
Microdata semantic-extend
 
WordPress Tips and Tricks (DFW Meetup)
WordPress Tips and Tricks (DFW Meetup)WordPress Tips and Tricks (DFW Meetup)
WordPress Tips and Tricks (DFW Meetup)
 
Eu odeio OpenSocial
Eu odeio OpenSocialEu odeio OpenSocial
Eu odeio OpenSocial
 
Jarrar: RDFa
Jarrar: RDFaJarrar: RDFa
Jarrar: RDFa
 
Advanced Structured Data: Beyond Rich Snippets
Advanced Structured Data: Beyond Rich SnippetsAdvanced Structured Data: Beyond Rich Snippets
Advanced Structured Data: Beyond Rich Snippets
 
[2019] HTTP API 설계 후회 고민
[2019] HTTP API 설계 후회 고민[2019] HTTP API 설계 후회 고민
[2019] HTTP API 설계 후회 고민
 
Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?
 
Proposed schema changes - have your say
Proposed schema changes - have your sayProposed schema changes - have your say
Proposed schema changes - have your say
 
Jarrar: RDFa
Jarrar: RDFaJarrar: RDFa
Jarrar: RDFa
 
Building Windows 8 Apps with Windows Azure
Building Windows 8 Apps with Windows AzureBuilding Windows 8 Apps with Windows Azure
Building Windows 8 Apps with Windows Azure
 
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
 
Redmine Betabeers SVQ
Redmine Betabeers SVQRedmine Betabeers SVQ
Redmine Betabeers SVQ
 
Associations & JavaScript
Associations & JavaScriptAssociations & JavaScript
Associations & JavaScript
 
FamilySearch Reference Client
FamilySearch Reference ClientFamilySearch Reference Client
FamilySearch Reference Client
 
Gem christmas calendar
Gem christmas calendarGem christmas calendar
Gem christmas calendar
 
Creating HTML Pages
Creating HTML PagesCreating HTML Pages
Creating HTML Pages
 
WordPress Hidden Gems (July 2011)
WordPress Hidden Gems (July 2011)WordPress Hidden Gems (July 2011)
WordPress Hidden Gems (July 2011)
 
Copy of-a-walk-around-westfall-plaza
Copy of-a-walk-around-westfall-plazaCopy of-a-walk-around-westfall-plaza
Copy of-a-walk-around-westfall-plaza
 
User Profiles: I Didn't Know I Could Do That? (Demo Slides)
User Profiles:  I Didn't Know I Could Do That?  (Demo Slides)User Profiles:  I Didn't Know I Could Do That?  (Demo Slides)
User Profiles: I Didn't Know I Could Do That? (Demo Slides)
 

Javaone 2009 Building RESTful APIs

  • 1. Building Consistent RESTful APIs in a High- Performance Environment Yegor Borovikov, Software Architect Brandon Duncan, Director of Engineering LinkedIn Corporation http://blog.linkedin.com/
  • 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. Examples of RESTful APIs What 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. Examples of RESTful APIs What’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. Examples of RESTful APIs Multiple 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. Examples of RESTful APIs Multiple 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. Typical Solution Variety 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. Domain Model as Foundation Sample 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. Domain Model as Foundation Follow 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. Domain Model as Foundation Fine-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. Domain Model as Foundation Fine-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. Domain Model as Foundation Fine-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. Domain Model as Foundation Benefits > 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. Examples of LinkedIn APIs HTTP 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. Examples of LinkedIn APIs HTTP PUT - Update > Set the user’s name: /people[/id=123] /id /name PUT 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. Examples of LinkedIn APIs HTTP POST - Create > Add a friend /people[/id=123] /id POST http://api.linkedin.com/v2/people/123/friends /name /email <friend uri=“urn:linkedin:v2:people/888”/> /photo /best-friend 201 Created /friends /456 Location: http://api.linkedin.com/v2/people/123/friends/888 /888 … 16
  • 17. Examples of LinkedIn APIs HTTP DELETE - Remove > Remove a friend DELETE http://api.linkedin.com/v2/people/123/friends/456 > Delete a company DELETE http://api.linkedin.com/v2/companies/exchange=NYSE&ticker=GM > Delete two companies DELETE http://api.linkedin.com/v2/companies::(664,665) 17
  • 18. Use Standard Headers > Content-Type > Last-Modified > Accept > Vary > Authorization > Cache-Control > Content-MD5 > Location > Warning 18
  • 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. Real-World Example Xobni 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