Domain: Factories should return collections of DTOs, not a single DTO
- a prerequisite of #40: workflow for Entity classes
- related to #60: DAOs should bind to Factory, not to an Entity
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")