DDD Repositórios
Yan.ts
Posted on May 5, 2022
Today I Learned 05/05/2022
Repositório
O Vaughn Vernon em seu livro Implementing Domain-Driven Design
define repositórios como:
Um repositório comumente se refere a um local de armazenamento, geralmente considerado um local de segurança ou preservação dos itens nele armazenados. Quando você armazena algo em um repositório e depois retorna para recuperá-lo, você espera que ele esteja no mesmo estado que estava quando você o colocou lá. Em algum momento, você pode optar por remover o item armazenado no repositório
VERNON, Vaughn. Implementing Domain-Driven DesignEsses objetos são semelhantes a coleções sobre persistência. Todo tipo de Agregado persistente terá um Repositório. De um modo geral, existe uma relação um-para-um entre um tipo de Agregado e um Repositório
VERNON, Vaughn. Implementing Domain-Driven Design
Ou seja, para cada agregado temos apenas um repositório então se por exemplo voltarmos no exemplo de agregados que eu dei no artigo sobre Services em DDD
Para esse aggregado de customer somente será criado um único repositório, que vai conter os campos de customer E os campos de endereço, não é necessário uma tabela para Address justamente por que o domínio da aplicação é diferente da infraestrutura
Não tem problema a gente implementar o banco de dados pensando em domínio, o problema é implementar o domínio pensando no banco de dados
Cenário
Imaginando uma entidade de order onde cada order precisa ter os seus items associados, sendo que nessa entidade precisamos salvar também o id do usuário que fez o pedido e o produto que é associado ao ordem item.
Porem final das contas o nosso aggregado vai ser esse daqui:
Implementação
Para fazermos o repositório do nosso agregado de order vamos precisar inicialmente de dois models, o model de OrderItem e o de Order. Vamos criar duas tabelas por banco de dados, lembrando que 1 repositorio corresponde 1 agregado, porem 1 repositorio não tem essa relação de 1 para 1 com tabela no banco de dados
(ps: o model foi feito utilizando sequelize porem o ORM utilizado não importa muito, isso pode ser implementado com qualquer um):
order-items.model.ts
@Table({
tableName: 'orders_items',
timestamps: false
})
export class OrderItemModel extends Model{
@PrimaryKey
@Column
declare id: string;
@ForeignKey(() => ProductModel)
@Column({allowNull: false})
declare product_id: string;
@BelongsTo(() => ProductModel)
declare product: ProductModel;
@ForeignKey(() => OrderModel)
@Column({allowNull: false})
declare order_id: string;
@BelongsTo(() => OrderModel)
declare order: OrderModel;
@Column({allowNull: false})
declare quantity: number;
@Column({allowNull: false})
declare name: string;
@Column({allowNull: false})
declare price: number;
}
order.model.ts
@Table({
tableName: 'orders',
timestamps: false
})
export class OrderModel extends Model{
@PrimaryKey
@Column
declare id: string;
@ForeignKey(() => CustomerModel)
@Column({allowNull: false})
declare customer_id: string;
@BelongsTo(() => CustomerModel)
declare customer: CustomerModel;
@HasMany(() => OrderItemModel)
declare items: OrderItemModel[]
@Column({allowNull: false})
declare total: number;
}
com os models declarados podemos criar o repository:
export class OrderRepository{
async create(entity: Order): Promise<void> {
await OrderModel.create({
id: entity.id,
customer_id: entity.customer_id,
total: entity.total(),
items: entity.items.map(item => ({
id: item.id,
name: item.name,
price: item.price,
quantity: item.quantity,
product_id: item.productId,
}))
},
{
include: [{model: OrderItemModel}]
})
}
}
Só precisamos do repositório de Orders, pois ele já se encarrega de quando criarmos uma nova order ele salvar os items na tabela de order-items
Ainda estou aprendendo sobre DDD e se quiser ver melhor o código pode dar uma olhada nesse Repositório
Posted on May 5, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.