Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Designing a Serverless Application with Domain Driven Design

1,882 views

Published on



With Serverless/FaaS the unit of work is a fine-grained, ephemeral function triggered by a variety of events. How can we design a system composed of countless functions without loosing sight of each function's purpose or without accidentally introducing a big ball of mud due to highly coupled functions. One approach could be by introducing Domain Driven Design (DDD). DDD is a methodology to capture a business domain as closely as possible into software coming with strategic and tactical design patterns. DDD helps to decompose a system into modular components (Bounded Contexts) and mapping the integration patterns between them (Context Mapping).

In this talk, I am going to highlight how Domain Driven Design and Serverless/FaaS can go together by splitting a system into Bounded Contexts and how these Bounded Contexts can be implemented by using Serverless technologies.

Published in: Technology

Designing a Serverless Application with Domain Driven Design

  1. 1. Designing a Serverless Application with Domain Driven Design Susanne Kaiser Independent Tech Consultant @suksr
  2. 2. $2,840,000,000,000 TWOTRILLIONEIGHTHUNDREDFOURTYBILLION USD Costs of Poor Software Quality in the US in 2018 (by CISQ report ) Source: https://www.it-cisq.org/the-cost-of-poor-quality-software-in-the-us-a-2018-report @suksr
  3. 3. Areas of Cost Relating To Poor Software Quality Source: https://www.it-cisq.org/the-cost-of-poor-quality-software-in-the-us-a-2018-report @suksr
  4. 4. Some Indicators for Poor Software Quality (extracted from CISQ report ) t Defects 0% Increasing defect trend Low test coverage Cyclomatic complexity Large inheritance depth High amount of effort to understand piece of code Badly engineered software Lack of domain knowledge Based on: https://www.it-cisq.org/the-cost-of-poor-quality-software-in-the-us-a-2018-report Communication and coordination breakdowns in (large) teams High degree of class coupling @suksr
  5. 5. Domain Driven Design (DDD) Business Domain Needs Strategy Software Design @suksr
  6. 6. Domain Driven Design (DDD) – Terminology Strategic Design Tactical Design Bounded Context Ubiquitous Language Core Subdomain Supporting Subdomain Generic Subdomain Problem Space Solution Space Context Maps Anti-Corruption Layer Shared Kernel Open Host Service Separate Ways Partnership Customer-Supplier Conformist Domain Model Entity Value Object Aggregate Repository Factory Application Service Domain Service Domain Event @suksr
  7. 7. DDD & Wardley Maps ValueChainInvisibleVisible Evolution Genesis Custom-Built Product (+rental) Commodity (+utility) Position Movement Uncharted Industrialised @suksr
  8. 8. ValueChain InvisibleVisible Evolution Visualisation of a value chain’s evolution Genesis Custom-Built Product (+rental) Commodity (+utility) Position Movement Wardley Maps BY SIMON WARDLEY Uncharted Industrialised @suksr
  9. 9. Wardley Maps – VALUE CHAIN Who are your users? ValueChain InvisibleVisible @suksr
  10. 10. Wardley Maps – VALUE CHAIN Who are your users? What are your users’ needs? ValueChain InvisibleVisible @suksr
  11. 11. Wardley Maps – VALUE CHAIN Who are your users? What are your users’ needs? What are the components/activities to fulfill your users’ needs incl. dependencies? ValueChain InvisibleVisible Position @suksr
  12. 12. Wardley Maps – LANDSCAPE ValueChain InvisibleVisible Evolution Components along evolution axes Genesis Custom-Built Product (+rental) Commodity (+utility) Position Movement @suksr
  13. 13. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Everything evolves Past Current Future Supply CompetitionDemand Competition Uncharted Industrialised Wardley Maps – PATTERNS Movement @suksr
  14. 14. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Past Current Future Characteristics changeUncharted Undefined market Uncertain Unpredictable Rare Poorly understood Forming market Learning on use Increasing understanding Slowly increasing consumption Rapid increases in learning Growing market Learning on operation Increasing education Rapidly increasing consumption Rapid increase in use Mature market Known / accepted Stable Widespread and stabilising Commonly understood (in term of use) Industrialised Wardley Maps – PATTERNS Movement @suksr
  15. 15. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Wardley Maps – PRINCIPLES Use appropriate methods per evolution stage Build in-house Use/buy off-the-shelf product Outsource to utility suppliers @suksr
  16. 16. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Use appropriate methods per evolution stage Wardley Maps – PRINCIPLES Build in-house Use/buy off-the-shelf product Outsource to utility suppliers @suksr
  17. 17. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Use appropriate methods per evolution stage Wardley Maps – PRINCIPLES Build in-house Use/buy off-the-shelf product Outsource to utility suppliers @suksr
  18. 18. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Know your users & focus on user needs Wardley Maps – PRINCIPLES Build in-house / Agile Use/buy off-the-shelf product / Lean Outsource to utility suppliers / Six Sigma @suksr
  19. 19. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution DDD & Wardley Maps Ubiquitous Language Domain Knowledge Understanding the problem domain first Problem Domain Domain Experts Development Teams Collaboration @suksr
  20. 20. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution DDD & Wardley Maps Problem Domain Strategic Design DDD Patterns & Practices Tactical Design @suksr
  21. 21. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution DDD & Wardley Maps Problem Domain Strategic Design DDD Patterns & Practices Tactical Design Analysing the business domain Discovering Subdomains Problem Space Decomposing into modular components (Bounded Contexts) Mapping interaction patterns between BC (Context Maps) Solution Space @suksr
  22. 22. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution DDD & Wardley Maps Problem Domain Strategic Design DDD Patterns & Practices Tactical Design Architecting a solution fitting the problem domain as closely as possible Provides building blocks to implement domain model Analysing the business domain Discovering Subdomains Problem Space Decomposing into modular components (Bounded Contexts (BC) Mapping interaction patterns between BC (Context Maps) Solution Space @suksr Solution Space
  23. 23. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Distilling the problem domain & discovering the core subdomain DDD & Wardley Maps Core Subdomain Problem Domain STRATEGIC DESIGN (PROBLEM SPACE) Supporting Subdomain Generic Subdomain ProblemSpace @suksr
  24. 24. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Distilling the problem domain & discovering the core subdomain DDD & Wardley Maps Core Subdomain Problem Domain Competitive advantage Complex Changes often Build in-house STRATEGIC DESIGN (PROBLEM SPACE) Supporting Subdomain Generic Subdomain ProblemSpace @suksr
  25. 25. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Distilling the problem domain & discovering the core subdomain DDD & Wardley Maps Core Subdomain Problem Domain Competitive advantage Complex Changes often Build in-house No competitive advantage Quite simple Does not change often Prefer to buy/use off-the-shelf STRATEGIC DESIGN (PROBLEM SPACE) Supporting Subdomain Generic Subdomain ProblemSpace @suksr
  26. 26. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Distilling the problem domain & discovering the core subdomain DDD & Wardley Maps Core Subdomain Problem Domain Competitive advantage Complex Changes often Build in-house No competitive advantage Quite simple Does not change often Prefer to buy/use off-the-shelf No competitive advantage Generally complex Does not change often Buy/use off-the-shelf / outsource STRATEGIC DESIGN (PROBLEM SPACE) Supporting Subdomain Generic Subdomain ProblemSpace @suksr
  27. 27. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Model Driven Design DDD & Wardley Maps STRATEGIC DESIGN (SOLUTION SPACE) Development Teams Domain Experts Ubiquitous Language Analysis Model Code Model Domain Model Core Subdomain Supporting Subdomain Generic Subdomain Problem Domain ProblemSpaceSolutionSpace abstracted by @suksr
  28. 28. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Bounded Contexts DDD & Wardley Maps STRATEGIC DESIGN (SOLUTION SPACE) Core Subdomain Supporting Subdomain Generic Subdomain Problem Domain ProblemSpaceSolutionSpace Linguistic/semantic boundary Ownership boundary Model boundary Physical boundary Different architectural patterns per context possible @suksr
  29. 29. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Know your users & focus on user needs Submit Session DDD & Wardley Maps STRATEGIC DESIGN (PROBLEM SPACE) Speaker @suksr
  30. 30. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps STRATEGIC DESIGN (PROBLEM SPACE) Discovering subdomains Supporting GenericCore @suksr
  31. 31. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps STRATEGIC DESIGN (SOLUTION SPACE) Supporting GenericCore Event Evaluation AccountSchedule MessageSession Domain Models SolutionSpace @suksr
  32. 32. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore Event Evaluation AccountSchedule Message Speaker Session CfP SolutionSpace STRATEGIC DESIGN (SOLUTION SPACE) Domain Models @suksr
  33. 33. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore Event Evaluation AccountSchedule Message Speaker Profile Submitted Session CfP Settings Recipient Open CfP Evaluated Session Scheduled Session SolutionSpace STRATEGIC DESIGN (SOLUTION SPACE) Domain Models @suksr
  34. 34. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore SolutionSpace STRATEGIC DESIGN (SOLUTION SPACE) Bounded Contexts Linguistic/semantic boundary Model integrity boundary Event Evaluation AccountSchedule MessageSubmitted Session CfP Settings Recipient Open CfP Evaluated Session Scheduled Session Speaker Profile Session Evaluation Submission Handling Event Mngmnt. Schedule Mngmnt. Messaging Account Handling @suksr
  35. 35. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore SolutionSpace STRATEGIC DESIGN (SOLUTION SPACE) Submission Handling Event Mngmnt. Session Evaluation Messaging Account Handling Schedule Mngmnt. Bounded Contexts Ownership boundary Linguistic/semantic boundary Model integrity boundary @suksr
  36. 36. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore SolutionSpace STRATEGIC DESIGN (SOLUTION SPACE) Submission Handling Event Mngmnt. Session Evaluation Messaging Account Handling Schedule Mngmnt. Bounded Contexts Ownership boundary Linguistic/semantic boundary Model integrity boundary Physical boundary SCM Data store CI/CD Artefact @suksr
  37. 37. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution ProblemSpace Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore SolutionSpace TACTICAL DESIGN Submission Handling Event Mngmnt. Session Evaluation Messaging Account Handling Schedule Mngmnt. Architectural Patterns Architectural patterns can differ per Bounded Context, e.g. StrategicDesignTacticalDesign Layered Architecture Hexagonal Architecture CQRS @suksr
  38. 38. Hexagonal Architecture Business Logic Application REST-API Port Port Message Broker Adapter Adapter Adapter Port Inner Outer Outside @suksr
  39. 39. Hexagonal Architecture Business Logic Application Port Adapter BOUNDED CONTEXT: EVENT MANAGEMENT EventController AWS API Gateway Port REST-API with AWS API-Gateway and AWS Lambda EventController AWS API Gateway newEvent deleteEvent activateEvent POST /events DELETE /events/{id} POST /events/{id}/activate Inner Outer Outside @suksr
  40. 40. export class EventsController { private readonly eventsService: EventApplicationService; public constructor(eventsService: EventApplicationService) { this.eventsService = eventsService; } public activateEvent: Handler = async (event: APIGatewayEvent, context: Context, callback: Callback) => { if (!event.pathParameters) { return callback(undefined, failure({ status: "error", error: "no event id specified" })); } if (!event.requestContext.authorizer) { return callback(undefined, failure({ status: "error", error: "no authorized user specified" })); } try { const eventId = new EventId(event.pathParameters.id); const userId = new UserId(event.requestContext.authorizer.claims['cognito:username']); await this.eventsService.activateEvent(eventId, userId); callback(undefined, success({status: "ok"})); } catch(e) { return callback(undefined, failure({ status: "error", error: e })); } }; public newEvent: Handler = async (event: APIGatewayEvent, context: Context, callback: Callback) => { // ... // } REST-API AdapterPort Lambda Function Lambda Function Hexagonal Architecture BOUNDED CONTEXT: EVENT MANAGEMENT @suksr
  41. 41. Hexagonal Architecture Business Logic Application Port BOUNDED CONTEXT: EVENT MANAGEMENT EventController AWS API Gateway Port Data Storage with AWS DynamoDB DynamoDBEventRepository Inner Outer Outside @suksr
  42. 42. export default class DynamoDBEventRepository implements EventRepository { private static TABLE_NAME: string = "events"; private readonly dynamoDbClient: AWS.DynamoDB.DocumentClient; constructor() { this.dynamoDbClient = new AWS.DynamoDB.DocumentClient(); } public async eventOfId(id: EventId): Promise<Event|null> { const params : DocumentClient.GetItemInput = { TableName: DynamoDBEventRepository.TABLE_NAME, Key: { eventId: id } }; const result: DocumentClient.GetItemOutput = await this.dynamoDbClient.get(params).promise(); const item: AttributeMap|undefined = result.Item; if (item) { const id = new EventId(item.eventId); const name = Name.create(item.name); const description = Description.create(item.description); const period = Period.create(item.period.startDate, item.period.endDate); return Event.create(id, name, item.eventStatus, period, description); } return null; } public saveEvent(event: Event) { const params : DocumentClient.PutItemInput = { // ... // }; return this.dynamoDbClient.put(params).promise(); } } Hexagonal Architecture Database AdapterPort DynamoDB Client BOUNDED CONTEXT: EVENT MANAGEMENT @suksr
  43. 43. Hexagonal Architecture Business Logic Application Port BOUNDED CONTEXT: EVENT MANAGEMENT EventController AWS API Gateway Port DynamoDBEventRepository Business Logic Implementation Inner Outer Outside @suksr
  44. 44. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore TACTICAL DESIGN Submission Handling Event Mngmnt. Session Evaluation Messaging Account Handling Schedule Mngmnt. Business Logic Implementation Patterns Business logic implementation patterns can differ per Bounded Context, e.g. Domain Model Active Record Transaction Script @suksr ProblemSpaceSolutionSpace StrategicDesignTacticalDesign
  45. 45. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore TACTICAL DESIGN Submission Handling Event Mngmnt. Session Evaluation Messaging Account Handling Schedule Mngmnt. Building Blocks of Domain Models ● Value Object ● Entity ● Aggregate ● Repository ● ApplicationService ● Domain Event ● ... @suksr ProblemSpaceSolutionSpace StrategicDesignTacticalDesign
  46. 46. Domain Model BC: EVENT MANAGEMENT Event create: Event activate reschedule rename EventId id: string Name create: Name name: string EventStatus CREATED ACTIVATED DEACTIVATED deactivate Description create: Description desc: string Period create: Period start: Date end: Date Value Object Entity Aggregate Root Aggregate Application Port EventController AWS API Gateway Port DynamoDBEventRepository Event @suksr
  47. 47. export default class Event { readonly id: EventId; name: Name; description?: Description; status: EventStatus; period: Period; private constructor(id: EventId, name: Name, status: EventStatus, period: Period, description?: Description) { this.id = id; this.name = name; this.description = description; this.status = status; this.period = period; } public activate() { if (this.status === EventStatus.CLOSED) { throw new Error("You cannot activate a closed event"); } if (this.status === EventStatus.ACTIVATED) { throw new Error("This event has already been activated"); } this.status = EventStatus.ACTIVATED; } public rename(name: Name) { if (!name) { throw new Error("You cannot rename the event to an empty name"); } this.name = name; } // ... // } Aggregate @suksr
  48. 48. Domain Model BC: EVENT MANAGEMENT Application EventController AWS API Gateway DynamoDBEventRepository Event EventApplicationService EventRepository @suksr
  49. 49. export default class EventApplicationService { private readonly eventRepository: EventRepository; constructor(eventRepository: EventRepository) { this.eventRepository = eventRepository; } public async activateEvent(id: EventId) { const event = await this.eventRepository.eventOfId(id); if (!event) { throw new Error("Could not deactivate event with id " + id + ", since event does not exist."); } event.activate(); await this.eventRepository.saveEvent(event); } // ... // } ApplicationService Domain Model EVENT MANAGEMENT @suksr
  50. 50. Domain Model EVENT MANAGEMENT Application EventController AWS API Gateway DynamoDBEventRepository Event EventApplicationService EventRepository export default interface EventRepository { saveEvent(event: Event): void; eventOfId(id: EventId): Promise<Event|null>; // ... // } @suksr
  51. 51. ValueChain InvisibleVisible Genesis Custom-Built Product (+rental) Commodity (+utility) Evolution Evaluate Submissions Manage Event Organiser Build & Publish Schedule Communicate w/ Speakers Signup/Signin Speaker Submit Session DDD & Wardley Maps Supporting GenericCore TACTICAL DESIGN Submission Handling Event Mngmnt. Session Evaluation Messaging Account Handling Schedule Mngmnt. DDD suits best for the core subdomain Movement Build in-house Use/buy off-the-shelf product Outsource to utility suppliers - or - - or - @suksr ProblemSpaceSolutionSpace StrategicDesignTacticalDesign
  52. 52. Business Domain Needs Strategy Better Software Design Ubiquitous Language Domain Knowledge Domain Experts Development Teams Collaboration Gaining Domain Knowledge Aligning Software Design to Business Domain Core Subdomain Discovering the Core Subdomain Do not apply DDD everywhere! Focus on your core! Core Subdomain DDD helps with ... @suksr But ...
  53. 53. Some References https://learnwardleymapping.com/ https://medium.com/wardleymaps https://miro.com/blog/wardley-maps-whiteboard-canvas/ https://community.wardleymaps.com/

×