Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Designing APIs: Less Data is More

Designing APIs: Less Data is More

Often developers design APIs that expose more than is needed - unnecessary fields, redundant relationships, and endpoints that no one asked for.

These kinds of practices later on introduce communication overhead, extra maintenance costs, negative performance impacts, and waste time that could have been spent better otherwise.

We'll walk through how to design minimal APIs that are straight forward to use, and that are exactly what our consumers need!

DamirSvrtan

April 13, 2021
Tweet

More Decks by DamirSvrtan

Other Decks in Programming

Transcript

  1. Designing APIs
    Damir Svrtan
    Less Data is More

    View full-size slide

  2. Damir Svrtan
    He/him
    Senior Software Engineer @ Netflix
    Twitter: @DamirSvrtan

    View full-size slide

  3. San Francisco 🇺🇸

    View full-size slide

  4. Zagreb 🇭🇷

    View full-size slide

  5. Designing APIs
    Less Data is More

    View full-size slide

  6. Avoiding overhead when
    designing APIs

    View full-size slide

  7. Bloated overly flexible APIs

    View full-size slide

  8. What kind of APIs?
    • HTTP based APIs
    • REST APIs, JSON APIs, GraphQL etc

    View full-size slide

  9. API technology agnostic
    Applicable for all kinds of APIs

    View full-size slide

  10. Blogging Platform

    View full-size slide

  11. Blogging Platform:
    • Authors can release posts
    • Posts can have comments

    View full-size slide

  12. Two principles for
    building APIs
    • Designing the minimal API surface
    • Designing from Strict to Loose

    View full-size slide

  13. 1st Principal
    Design the minimal API surface

    View full-size slide

  14. Bloated API surface:
    - redundant fields
    - redundant relationships
    - redundant input fields

    View full-size slide

  15. Don’t Expose Redundant
    Fields

    View full-size slide

  16. Requirement:
    “Show the author of the blogpost”

    View full-size slide

  17. CREATE TABLE authors (
    id
    first_name
    last_name
    email
    avatar_url
    );

    View full-size slide

  18. Friendly API developer:
    “Let’s expose the email, someone might find it
    useful in the future”

    View full-size slide

  19. type Author {
    id
    firstName
    lastName
    avatarUrl
    email
    }

    View full-size slide

  20. 6 months later:
    Privacy reasons: stop exposing the email

    View full-size slide

  21. ..deprecation cycle..

    View full-size slide

  22. ..extreme amounts of communication..

    View full-size slide

  23. ..breaking clients..

    View full-size slide

  24. ..extreme amounts redundant cycles..

    View full-size slide

  25. Don’t Expose Redundant
    Relationships

    View full-size slide

  26. Requirement:
    “Indicate whether a post was reviewed”

    View full-size slide

  27. type Post {
    title:String
    body:String
    }

    View full-size slide

  28. type Post {
    title:String
    body:String
    reviewed:Boolean
    }

    View full-size slide

  29. Friendly API developer:
    “Let’s expose the reviewer for future use
    cases”

    View full-size slide

  30. type Post {
    title:String
    text:String
    reviewed:Boolean
    reviewer: Reviewer
    }

    View full-size slide

  31. Development costs are growing;
    - batch/eager loading
    - testing
    - performance impacts

    View full-size slide

  32. type Post {
    title:String
    text:String
    reviewed:Boolean
    reviewers: [Reviewer]
    }
    type Post {
    title:String
    text:String
    reviewed:Boolean
    reviewer: Reviewer
    }

    View full-size slide

  33. ..deprecation cycle..

    View full-size slide

  34. ..breaking clients..

    View full-size slide

  35. Delaying Decisions
    Adding later when we have more knowledge is better

    View full-size slide

  36. It’s easier to add in the future than to
    remove

    View full-size slide

  37. Don’t Expose Redundant
    Input Fields

    View full-size slide

  38. Requirement:
    “Readers need to be able to create and
    update comments”

    View full-size slide

  39. input CreateComment {
    postId: ID
    body: String
    }

    View full-size slide

  40. The friendly API developer:
    “Let’s have parity between inputs”

    View full-size slide

  41. input UpdateComment {
    id: ID
    postId: ID
    body: String
    }

    View full-size slide

  42. The blogging platform doesn’t support
    comment transitions from one post to another

    View full-size slide

  43. input UpdateComment {
    id: ID
    postId: ID
    body: String
    }

    View full-size slide

  44. Avoid anemic data modeling

    View full-size slide

  45. Ambiguity deteriorates
    Developer Experience

    View full-size slide

  46. YAGNI
    You Ain’t Gonna Need It

    View full-size slide

  47. 2nd Principal
    Strict to Loose

    View full-size slide

  48. - Avoid extra flexibility
    - Breaks First!

    View full-size slide

  49. Avoid extra flexibility

    View full-size slide

  50. Requirement:
    “The users need to be able to see comments
    on a post”

    View full-size slide

  51. comments(postId: ID @required)

    View full-size slide

  52. The friendly API developer:
    “Our clients might want to fetch all comments
    in the future”

    View full-size slide

  53. comments(postId: ID @optional)

    View full-size slide

  54. Unneeded application logic

    View full-size slide

  55. If postId.present?

    else

    end

    View full-size slide

  56. More code = More maintenance

    View full-size slide

  57. More code = More tests

    View full-size slide

  58. On inputs, it’s easy to go from required to
    optional, not the other way around

    View full-size slide

  59. Strict to Loose gives you more
    control

    View full-size slide

  60. Loose to Strict
    is a breaking change

    View full-size slide

  61. Breaks First!

    View full-size slide

  62. Requirement:
    “Ability to fetch comments for a post”

    View full-size slide

  63. The friendly API developer:
    “Let’s just give them an array of comments,
    we don’t need pagination!”

    View full-size slide

  64. The friendly API developer:
    “Let’s just give them an array of comments,
    we don’t need pagination yet!”

    View full-size slide

  65. comments(postId: ID): [Comment]

    View full-size slide

  66. The friendly API developer:
    “We won’t have more than 5 comments per
    post!”

    View full-size slide

  67. 6 months after:
    “There’s posts with 100’s of comments”

    View full-size slide

  68. Developer:
    “Let’s add pagination”

    View full-size slide

  69. comments(postId: ID): PaginatedComments

    View full-size slide

  70. Work is done, let’s go home!

    View full-size slide

  71. comments(postId: 1, first: 1000)

    View full-size slide

  72. The Friendly API Developer didn’t
    add limits to pagination

    View full-size slide

  73. Add pagination limitations from the
    beginning

    View full-size slide

  74. Error Message:
    Requesting 1000 records exceeds the `first`
    limit of 100 records.

    View full-size slide

  75. Super hard to add retroactively, but super
    easy to adjust in the future.

    View full-size slide

  76. How to avoid these overheads?

    View full-size slide

  77. Adopt Schema First Design

    View full-size slide

  78. Talk to your clients

    View full-size slide

  79. Be responsive to your clients
    requests

    View full-size slide

  80. There’s always exceptions

    View full-size slide

  81. Platform APIs

    View full-size slide

  82. Constraints due to release
    cycles

    View full-size slide

  83. Redundant work slows down
    progress on important features

    View full-size slide

  84. “The road to hell is paved with good
    intentions”

    View full-size slide

  85. Thank you! 👋
    Twitter: @DamirSvrtan

    View full-size slide