Typescript API Repositories and Unit of Work implementation (Domain-Driven Design)

Viewed 1924

I'm trying to implement Repositories and the Unit of Work pattern using Sequelize and Typescript in the existing project, following Domain-Driven Design. However, I encountered some difficulties due to a lack of relevant examples on the internet.

Let's consider the following code example.

interface IPostRepo {
    save(post: Post): Promise<void>;
}

interface ICommentRepo {
    save(comment: Comment): Promise<void>;
    saveBulk(comments: Comment[]): Promise<void>;
}

class SequelizePostRepo implements IPostRepo {
    private models: any;
    private commentRepo: ICommentRepo;

    constructor(models: any, commentRepo: ICommentRepo) {
        this.models = models;
        this.commentRepo = commentRepo;
    }

    public async save(post: Post): Promise<void> {
        const PostModel = this.models.Post;
        const rawSequelizePost = await PostMap.toPersistence(post);

        await PostModel.create(rawSequelizePost);
        await this.commentRepo.saveBulk(comments);
    }
}

class SequelizeCommentRepo implements ICommentRepo {
    private models: any;

    constructor(models: any) {
        this.models = models;
    }

    async save(comment: Comment): Promise<void> {
        const CommentModel = this.models.Comment;
        const rawSequelizeComment = CommentMap.toPersistence(comment);

        await CommentModel.create(rawSequelizeComment);
    }

    async saveBulk(comments: Comment[]): Promise<void> {
        for (let comment of comments) {
            await this.save(comment);
        }
    }
}

NOTE: The code is not complete and simplified for the problem demonstration purpose.

IPostRepo and ICommentRepo are contracts for the specific implementation such as SequelizePostRepo and SequelizeCommentRepo. Both of them implement a basic save method that operates on Domain Entities: Post and Comment. The Post is the Aggregate Root (models object contains the essential Sequelize models definition).

class CreatePostWithComments implements UseCase {
    private postRepo: IPostRepo;

    constructor (postRepo: IPostRepo) {
        this.postRepo = postRepo;
    }

    public async execute (req: ReplyToPostDTO) {

        /**
         *
         * More logic related to post and comments creation goes here
         *
         */

        post.addComment(comment1);
        post.addComment(comment2);
        post.addComment(comment3);

        await this.postRepo.save(post);
    }
}

Having CreatePostWithComments Use Case in the end I want to save Post Aggregate with attached comments. I'd like to do it in a single MySQL transaction using the Unit of Work pattern correctly.

I would appreciate any help that indicates correct implementation using simple examples.

I found the following package: https://github.com/pilagod/uow-sequelize, however by virtue of documentation deficiency I don't know how to use it rightly.

0 Answers
Related