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 Slide

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

    View Slide

  3. San Francisco 🇺🇸

    View Slide

  4. Zagreb 🇭🇷

    View Slide

  5. Designing APIs
    Less Data is More

    View Slide

  6. Avoiding overhead when
    designing APIs

    View Slide

  7. Bloated overly flexible APIs

    View Slide

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

    View Slide

  9. API technology agnostic
    Applicable for all kinds of APIs

    View Slide

  10. Blogging Platform

    View Slide

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

    View Slide

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

    View Slide

  13. 1st Principal
    Design the minimal API surface

    View Slide

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

    View Slide

  15. Don’t Expose Redundant
    Fields

    View Slide

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

    View Slide

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

    View Slide

  18. View Slide

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

    View Slide

  20. type Author {
    id
    firstName
    lastName
    avatarUrl
    email
    }

    View Slide

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

    View Slide

  22. ..deprecation cycle..

    View Slide

  23. ..extreme amounts of communication..

    View Slide

  24. ..breaking clients..

    View Slide

  25. ..extreme amounts redundant cycles..

    View Slide

  26. Don’t Expose Redundant
    Relationships

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  34. ..deprecation cycle..

    View Slide

  35. ..breaking clients..

    View Slide

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

    View Slide

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

    View Slide

  38. Don’t Expose Redundant
    Input Fields

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  45. Avoid anemic data modeling

    View Slide

  46. View Slide

  47. Ambiguity deteriorates
    Developer Experience

    View Slide

  48. YAGNI
    You Ain’t Gonna Need It

    View Slide

  49. 2nd Principal
    Strict to Loose

    View Slide

  50. - Avoid extra flexibility
    - Breaks First!

    View Slide

  51. Avoid extra flexibility

    View Slide

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

    View Slide

  53. comments(postId: ID @required)

    View Slide

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

    View Slide

  55. comments(postId: ID @optional)

    View Slide

  56. Unneeded application logic

    View Slide

  57. If postId.present?

    else

    end

    View Slide

  58. More code = More maintenance

    View Slide

  59. More code = More tests

    View Slide

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

    View Slide

  61. Strict to Loose gives you more
    control

    View Slide

  62. Loose to Strict
    is a breaking change

    View Slide

  63. Breaks First!

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  70. Developer:
    “Let’s add pagination”

    View Slide

  71. comments(postId: ID): PaginatedComments

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  75. Add pagination limitations from the
    beginning

    View Slide

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

    View Slide

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

    View Slide

  78. How to avoid these overheads?

    View Slide

  79. Adopt Schema First Design

    View Slide

  80. Talk to your clients

    View Slide

  81. Be responsive to your clients
    requests

    View Slide

  82. There’s always exceptions

    View Slide

  83. Platform APIs

    View Slide

  84. Constraints due to release
    cycles

    View Slide

  85. Conclusion

    View Slide

  86. Redundant work slows down
    progress on important features

    View Slide

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

    View Slide

  88. Thank you! 👋
    Twitter: @DamirSvrtan

    View Slide