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

Why the fuzz about serverless (with CompassDigital)

Why the fuzz about serverless (with CompassDigital)

Slides from my talk at CompassDigital

Yan Cui

May 12, 2024
Tweet

More Decks by Yan Cui

Other Decks in Technology

Transcript

  1. 1. What is serverless and why you should care 2.

    Who’s using serverless? 3. Serverless- fi rst, not serverless-only 4. Patterns & Anti-Patterns 5. The case for GraphQL & AppSync 6. Q&A
  2. Gojko Adzic It is serverless the same way WiFi is

    wireless. http://bit.ly/2yQgwwb
  3. Serverless means… don’t need to worry about scaling don’t need

    to provision and manage servers don’t pay for it if no-one uses it
  4. Lambda S3 SQS SNS Step Functions API Gateway DynamoDB AppSync

    Kinesis EventBridge Cognito You can build pretty much everything with serverless.
  5. User Tra ff i c Cost Serverless Cost per transaction

    is highly predictable Cost tracks usage closely
  6. WASTE User Tra ff i c Cost Serverless Serverful Cost

    can be predictable, but you overpay Cost per transaction is highly predictable Cost tracks usage closely
  7. Donald Knuth We should forget about small ef fi ciencies,

    say about 97% of the time: premature optimization is the root of all evil.
  8. cost of the conversation: ~$50 per dev per hour x

    8 = $400 potential saving: $10/month
  9. cost of the conversation: ~$50 per dev per hour x

    8 = $400 potential saving: $10/month break-even time for conversation: $400 ÷ $10/month = 40 months!!!
  10. Donald Knuth We should forget about small ef fi ciencies,

    say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.
  11. HW Ownership OS Runtime & Scale Code Focus on getting

    there! Physical Servers Virtual Machines Containers Serverless
  12. Streaming live sporting events 2 million+ concurrent users at peak

    Mix of containers and serverless Serverless for APIs, event processing, etc.
  13. Evolution Architecture "an approach to building software that's designed to

    evolve over time as business priorities change, customer demands shift, and new technologies emerge."
  14. “We can solve any problem by introducing an extra level

    of indirection.” Fundamental Theorem of Software Engineering
  15. ?

  16. ? ?

  17. container Optimize for efficiency Gains traction serverless Fast time-to-market Caller

    shouldn’t have to rewrite their app when you change an implementation detail
  18. ?

  19. ?

  20. Lambdalith Pros & Cons Familiar web framework Testing is easier

    No per-endpoint metric & alert Less fine-grained access control
  21. Lambdalith Pros & Cons Familiar web framework Testing is easier

    No per-endpoint metric & alert Less fine-grained access control Limited auth support
  22. Lambdalith Pros & Cons Familiar web framework Testing is easier

    No per-endpoint metric & alert Less fine-grained access control Limited auth support Large frameworks affect performance
  23. Lambdalith Pros & Cons Familiar web framework Testing is easier

    No per-endpoint metric & alert Less fine-grained access control Limited auth support Large frameworks affect performance Custom app metric with EMF
  24. Lambdalith Pros & Cons Familiar web framework Testing is easier

    No per-endpoint metric & alert Less fine-grained access control Limited auth support Large frameworks affect performance Custom app metric with EMF In-function authentication
  25. Lambdalith Pros & Cons Familiar web framework Testing is easier

    No per-endpoint metric & alert Less fine-grained access control No per-endpoint auth Large frameworks affect performance Custom app metric with EMF In-function authentication YOU pay for unauthorised requests
  26. Lambdalith Pros & Cons Familiar web framework Testing is easier

    No per-endpoint metric & alert Less fine-grained access control No per-endpoint auth Large frameworks affect performance Harder to tune performance & cost
  27. schema { query: Query mutation: Mutation } type Query {

    getProfile(id: ID!): Profile } ! = required ID is a built-in type
  28. Profile is a type schema { query: Query mutation: Mutation

    } type Query { getProfile(id: ID!): Profile }
  29. schema { query: Query mutation: Mutation } type Query {

    getProfile(id: ID!): Profile } type Profile { id: ID! firstName: String! lastName: String! }
  30. schema { query: Query mutation: Mutation } type Query {

    getProfile(id: ID!): Profile @aws_lambda } type Profile { id: ID! firstName: String! lastName: String! } type Mutation { createProfile( firstName: String! lastName: String! ): Profile }
  31. GET https://myapp.com/user/1234 REST API { “id”: “1234”, “firstName”: “Yan”, “lastName”:

    “Cui”, “dob”: “…”, … } Returns data we don’t need Overfetching
  32. GET https://myapp.com/user/1234 REST API { “id”: “1234”, “firstName”: “Yan”, “lastName”:

    “Cui”, “dob”: “…”, … } Doesn’t have everything we need
  33. GraphQL API POST https://myapp.com/graphql { getProfile (id: “1234”) { firstName

    lastName } } { “firstName”: “Yan”, “lastName”: “Cui” }
  34. GraphQL API POST https://myapp.com/graphql { getProfile (id: “1234”) { friends

    { firstName lastName } } } { “friends”: [{ “firstName”: “Gerard”, “lastName”: “Sans” }, { “firstName”: “Ant”, “lastName”: “Stanley” }] }
  35. Strongly typed contract between client and server Built-in request &

    response validation Mitigates data exfiltration risks
  36. AppSync full request caching Shared, static data are fetched multiple

    times $context.arguments & $context.identity
  37. AppSync per-resolver caching Can specify different TTL & cache key

    for each resolver Shared data is fetched once and cached
  38. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost: Post @aws_subscribe(mutations: [“addPost"]) }
  39. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost: Post @aws_subscribe(mutations: [“addPost“]) }
  40. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost: Post @aws_subscribe(mutations: [“addPost“]) } subscriber publisher subscriber subscriber
  41. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost: Post @aws_subscribe(mutations: [“addPost“]) } publisher subscriber subscriber subscriber
  42. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost: Post @aws_subscribe(mutations: [“addPost“]) } publisher subscriber subscriber subscriber
  43. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost(author: String, title: String, publishYear: Int, publishMonth: Int) : Post @aws_subscribe(mutations: [“addPost“]) }
  44. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost(author: String, title: String, publishYear: Int, publishMonth: Int) : Post @aws_subscribe(mutations: [“addPost“]) } subscriber subscriber subscriber
  45. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost(author: String, title: String, publishYear: Int, publishMonth: Int) : Post @aws_subscribe(mutations: [“addPost“]) } subscriber publisher subscriber subscriber
  46. type Mutation { addPost(id: ID! author: String! title: String content:

    String url: String): Post! } type Subscription { addedPost(author: String, title: String, publishYear: Int, publishMonth: Int) : Post @aws_subscribe(mutations: [“addPost“]) } subscriber publisher subscriber subscriber
  47. AppSync + Lambda + DynamoDB is the most efficient way

    to build data-driven applications