2021-12-07
|~2 min read
|276 words
I was working on a project recently that was using Mongo as its data store. Unforuntately, because I was using the node driver for mongodb
directly, I wasn’t getting the type safety I like.
Part of this was my poor design (guilty!). But part of this was also how the node driver is typed to interact with the database.
Take my fetchTodos
for example:
const todos = _db.collection("todo")
export const fetchTodos = async (
query?: Filter<WithId<Document>>,
options?: FindOptions<Document>,
): Promise<any | Todo[]> => {
const found = query ? todos.find(query, options) : todos.find()
const foundResults = await found.toArray()
// TODO: Consider converting to a stream
return foundResults
}
I would have liked to be able to narrow my query only to elements on the Todo
model, but I couldn’t figure out how.
By leveraging Mongoose, however, I was able to simplify the logic and make sure that my queries were strongly typed.
export const fetchTodos = async (
query?: FilterQuery<Todo>,
): Promise<any | Todo[]> => {
return await dal.findTodo(query)
}
An example of replacing Mongo’s native driver with Mongoose is in this pull request.
The other thing I like about this change set is that I split the ologic between my service and the data access layer (dal) more cleanly. As I add in user authentication, I think this separation of concerns will pay dividends.
It’s worth noting that I’m currently relying on a single connection. If I wanted to convert to multiple connections, I might have to switch from exporting the model to exporting schemas and leverage Mongoose’s createConnection
instead of connect
method.
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!