DEV Community

Yan.ts
Yan.ts

Posted on

DDD Repositórios

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 Design

Esses 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

Aggregado de customer

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:

Exemplo da entidade

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;

}

Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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}]
    })
  }

}
Enter fullscreen mode Exit fullscreen mode

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

Latest comments (0)