Skip to content

Instantly share code, notes, and snippets.

@garciparedes
Last active May 12, 2022 10:36
Show Gist options
  • Select an option

  • Save garciparedes/1298957f78f2bab18a8a0861275ed88c to your computer and use it in GitHub Desktop.

Select an option

Save garciparedes/1298957f78f2bab18a8a0861275ed88c to your computer and use it in GitHub Desktop.
Migrate to [email protected]
  • Add the following packages to pyproject.toml:

    • minos-microservice-transactions
  • Update the config.yml file as follows:

    • Replace minos.aggregate.DatabaseTransactionRepository by minos.transactions.DatabaseTransactionRepository.
    • Replace minos.aggregate.DatabaseEventRepository by minos.aggregate.DatabaseDeltaRepository.
    • Remove minos.aggregate.TransactionServiceminos.aggregate.TransactionService from the services section.
    • Add the following fields to the aggregate section as follows (replacing MyAggregate with the corresponding class name):
...
aggregate:
  client: src.aggregates.MyAggregate
  publisher:
    client: minos.networks.TransactionalBrokerPublisher
    repository: minos.networks.DatabaseBrokerPublisherTransactionRepository
  ...
...
  • Update source code as follows:
    • Replace minos.aggregate.Event as minos.aggregate.Delta.
    • Replace minos.aggregate.RootEntity by minos.aggregate.Entity.
    • Remove minos.aggregate.ExternalEntity and use pass the class name as str to the minos.aggregate.Ref type hint. Here is an example:
# Old Approach


class Review(RootEntity):
    product: Ref[Product]


class Product(ExternalEntity):
    pass
# New Approach


class Review(Entity):
    product: Ref["src.aggregates.Product"]
  • Stop using MyEntity.get, MyEntity.find, MyEntity.save, MyEntity.create, MyEntity.update, MyEntity.delete, etc. methods and replace them by EntityRepository.get, EntityRepository.find, EntityRepository.save, EntityRepository.create, EntityRepository.update, EntityRepository.delete, etc. (Note that EntityRepository is accessible as the repository attribute of the MyAggregate class. The MyAggregate class is accesible as the aggregate attribute of the MyCommandService and MyQueryService classes. Here is an example:
# Old approach


class MyCommandService:
    async def handle(self, request: Request) -> Response:
        obj = await MyEntity.create(foo="bar")
        return Response(obj)
# New approach


class MyCommandService:
    async def handle(self, request: Request) -> Response:
        obj = await self.aggregate.create_one(foo="bar")
        return Response(obj)
 
 
class MyAggregate(Aggregate[MyEntity]):
    async def create(self, foo: str) -> MyEntity:
        obj, delta = await self.repository.create(MyEntity, foo=foo)
        await self.publish_domain_event(delta)
        return obj
  • Store sub-Entity instances independenty. Here is an example:
# Old Approach


class MyEntity(RootEntity):
    entries: EntitySet[MySubEntity]
    
    
class MySubEntity(Entity):
    number: int


class MyAggregate(Aggregate[Entity]):
    async def add_sub_entity(obj: MyEntity, entry: MySubEntity):
        obj.entries.add(entry)
        await obj.save()
# New Approach


class MyEntity(Entity):
    entries: EntitySet[Ref[MySubEntity]]
    
    
class MySubEntity(Entity):
    number: int


class MyAggregate(Aggregate[Entity]):
    async def add_sub_entity(obj: MyEntity, entry: MySubEntity):
        delta = self.repository.save(entry)
        await self.publish_domain_event(delta)
        obj.entries.add(entry)
        delta = await self.repository.save(obj)
        await self.publish_domain_event(delta)
        
  • As methods to directly interact with the database are not directly accesible from MyEntity anymore, in case of the saga methods, it's necessary to call the MyAggregate class to access the RepositoryEntity and efectively read or store entities. To do that, use the Dependency Injection system supported by the minos.common.Inject decorator. Here is an example:
# Old approach


async def commit_callback(context: SagaContext) -> SagaContext:
    order = await MyEntity.create(foo=context["bar"])
    return SagaContext(order=order)
# New approach


@Inject()
async def commit_callback(context: SagaContext, aggregate: MyAggregate) -> SagaContext:
    order = await aggregate.create(foo=context["bar"])
    return SagaContext(order=order)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment