Way to pass mongo session in repository pattern

Hi, I know this is not really Mongo related problem, but I’ve implemented repository pattern in my NodeJS so far. It works like this:

class BookService {
	private repo: BookRepository;

	constructor() {
		this.repo = new BookRepository();
	}

	createBook = async (param) => {
		return await this.repo.createBook(param)
        }
}

class BookRepository {
	collection: Collection;

	constructor() {
		this.collection = db.collection("books");
	}

	createBook = async (param) => {
		const session = client.startSession();
		session.startTransaction();

		try {
			const newDocument = (
				await this.collection.insertOne(param, { session })
			).ops[0];

			await session.commitTransaction();
			return newDocument;
		} catch (e) {
			if (session.inTransaction()) await session.abortTransaction();
			throw e;
		} finally {
			await session.endSession();
		}
	};
}

There is an “Author” service that’s also implemented the same.
My use cases are like this

Case 1:
bookService().createBook()

Case 2:
Promise.all([
   bookService().createBook(),
   authorService().createAuthor()	
])

With case 1, the method benefits from mongodb session and transaction. But with case 2, I cant seem to find a clean way to pass session object down to both book and author collection. The obvious way is to create the object outside the two services, and pass it down the services and the repositories. Something like this:

class BookRepository {
	collection: Collection;

	constructor() {
		this.collection = db.collection("books");
	}

	createBook = async (param, {session}) => {
		const newDocument = (await this.collection.insertOne(param, { session })).ops[0];
	};
}


class BookService {
	private repo: BookRepository;

	constructor() {
		this.repo = new BookRepository();
	}

	createBook = async (param, {session}) => {
		return await this.repo.createBook(param, {session})
        }
}

const session = client.startSession();
session.startTransaction();
Promise.all([
   bookService().createBook(param, {session}),
   authorService().createAuthor(param, {session})	
])

I think it’s not really scalable. Anyone has the same experience or a solution for this problem? Thank you for reading.

1 Like

im facing the same scenario… did you manage to solve it ?

Did anyone manage to solve this?