Slide 1

Slide 1 text

© 2021, Amazon Web Services, Inc. or its Affiliates.

Slide 2

Slide 2 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Atsushi Fukui Senior Solutions Architect Serverless Specialist Amazon Web Services Japan DDD on AWS Lambda How to implement your domain models on your AWS Lambda function JAWS PANKLATION 2021 2021/11/20

Slide 3

Slide 3 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Who am I v Name v Atsushi Fukui / twitter: afukui@ v Role and company v Senior Solutions Architect Serverless Specialist v Amazon Web Services Japan v Interests v Software Architecture, Object Oriented Design and programming, Agile Development process v My favorite AWS Services v AWS Lambda, AWS Step SQS and other all serverless services

Slide 4

Slide 4 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Agenda o Domain Driven Design (DDD) o Hexagonal Architecture o Domain models for sample application o How to implement unit testing code o Demo o Conclusion

Slide 5

Slide 5 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Domain-driven design o Provides a broad framework for making design decisions and developing a technical vocabulary for discussing domain design o Ubiquitous language - modeling the language of the business o Provides guidance about tactical design - model domains with entities, value objects, repositories and services, and strategic design…

Slide 6

Slide 6 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Hexagonal architecture Domain Model Ports Adapters Primary Actor Secondary Actor HTTP Request Event Message Queue … File Storage Database Queue …

Slide 7

Slide 7 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Sample Senario o Vaccination reservation system o Use cases: o A recipient can search for some vacant slots and register a reservation slot for vaccination reservation. o A recipient cannot register her reservation if there is no vacant slot. o A recipient cannot reserve her reservations more than two slots. o A recipient cannot reserve two reservations if there are same date time. There are pure business logics you need to implement on your domain model.

Slide 8

Slide 8 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Class diagram: register vaccination reservation

Slide 9

Slide 9 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Sequence diagram: register vaccination reservation

Slide 10

Slide 10 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Hexagonal architecture with the Lambda function Domain Model Ports Adapters Amazon API Gateway Amazon DynamoDB AWS Lambda function

Slide 11

Slide 11 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Implement domain models

Slide 12

Slide 12 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Domain models from slot import Slot class Recipient: def __init__(self, recipient_id:str, email:str, first_name:str, last_name:str, age:int): self.__recipient_id = recipient_id …. @property def recipient_id(self): return self.__recipient_id … def add_reserve_slot(self, slot:Slot) -> bool: if self.are_slots_same_date(slot): return False if self.is_slot_counts_equal_or_over_two(): return False self.__slots.append(slot) slot.use_slot()

Slide 13

Slide 13 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Unit testing for functions

Slide 14

Slide 14 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Unit test for Domain Model def test_cannot_append_slot_more_than_two(fixture_recipient, fixture_slot, fixture_slot_2, fixture_slot_3): slot = fixture_slot slot2 = fixture_slot_2 slot3 = fixture_slot_3 target = fixture_recipient target.add_reserve_slot(slot) target.add_reserve_slot(slot2) ret = target.add_reserve_slot(slot3) assert False == ret assert 2 == len(target.slots) def test_cannot_append_same_date_slot(fixture_recipient, fixture_slot): slot = fixture_slot target = fixture_recipient target.add_reserve_slot(slot) ret = target.add_reserve_slot(slot) assert False == ret assert 1 == len(target.slots)

Slide 15

Slide 15 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Unit test for Ports and Adapters classes class DummyRecipientAdapter(IRecipientAdapter): def load(self, recipient_id:str) -> Recipient: return Recipient(recipient_id, email, first_name, last_name, age) def save(self, recipient:Recipient) -> bool: return True class DummyModule(Module): def configure(self, binder): binder.bind(RecipientPort, to=RecipientPort(DummyRecipientAdapter())) @pytest.fixture() def fixture_recipient_port(): injector = Injector([DummyModule]) recipient_port = injector.get(RecipientPort) return recipient_port

Slide 16

Slide 16 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Unit test for Ports and Adapters classes def test_recipient_port_recipient_by_id(fixture_recipient_port): target = fixture_recipient_port recipient_id = "dummy_number" recipient = target.recipient_by_id(recipient_id) assert recipient != None assert recipient_id == recipient.recipient_id assert email == recipient.email assert first_name == recipient.first_name assert last_name == recipient.last_name assert age == recipient.age

Slide 17

Slide 17 text

© 2021, Amazon Web Services, Inc. or its Affiliates. app.py calls concrate class instances class RequestPortModule(Module): def configure(self, binder): binder.bind(ReservationService, to=ReservationService( RecipientPort(DDBRecipientAdapter()), SlotPort(DDBSlotAdapter()))) def lambda_handler(event, context): body = json.loads(event['body']) recipient_id = body['recipient_id'] slot_id = body['slot_id'] injector = Injector([RequestPortModule]) request_port = injector.get(RequestPort) status = request_port.make_reservation(recipient_id, slot_id)

Slide 18

Slide 18 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Demo

Slide 19

Slide 19 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Summary o Loosely coupling and strong encapsulation are key concept. o Hexagonal architecture is an architecture pattern used for encapslating domain logic, and decoupling it from other implementaion details, such as infrastructure or client requests. o This approach can help create separetion of concerns and sepalate the domain logic from the infrastructure. o Inversion of control (IoC) or injecting object instances is useful for unit testing with mock or fake objects.

Slide 20

Slide 20 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Please see my sample project on GitHub o https://github.com/afukui/jaws-pankration-ddd-lambda

Slide 21

Slide 21 text

© 2021, Amazon Web Services, Inc. or its Affiliates. Thank you!