pcah/python-clean-architecture

Domain: Factories should return collections of DTOs, not a single DTO

lhaze opened this issue · 1 comments

lhaze commented
  • a prerequisite of #40: workflow for Entity classes
  • related to #60: DAOs should bind to Factory, not to an Entity
lhaze commented

Let's look into a somewhat common use-case: an entity has a list of other instances as its components. For example, let's take an Invoice entity with a list of InvoiceFields. Elements of this list can be modeled with a ValueObject model (an "inline" submodel, represented by PostgreSQL JSONB column) or with a sub-entity (represented by a separate table and attached to an Invoice by a foreign key). Either way, both InvoiceRepository and Invoice should be unaware of the choice of modeling type.

class Invoice(Entity):
    fields: t.List['InvoiceField'] = related(field='invoice', nullable=False)


class InvoiceField(Entity):  # or a ValueObject
    invoice: Invoice
    quantity: int
    product: Product

Next, there's a Factory that models the complexity of the creation of an Invoice instance. Let's use MarshmallowFactory for that, and we won't use any implicit field generation.

class InvoiceFactory(MarshmallowFactory):
    class InvoiceSchema(marshmallow.Schema):
        fields = fields.Nested("InvoiceFieldSchema", many=True, exclude=("invoice",))
        class Meta:
            fields = ("__id__",)  # ooopsie, a somewhat accidental name conflict

    class InvoiceFieldSchema(marshmallow.Schema):
        class Meta:
            fields = ("__id__", "quantity", "product", "invoice")