I am a newbie to node.js, coming from a .net background. I would like to use some of the design patterns I used with c#.net. I am running into a few complications however, due to the differences in object oriented nature between c# and JavaScript.
In particular, I would like to implement the repository pattern but have not been able to find a lot of examples doing this with node. The way JavaScript and mongoose are set up are making it a little hard to wrap my mind around this one.
I was referred to the following url for an example https://github.com/iainjmitchell/mongorepositiory, I could be wrong, but I do not see where this example allows for you to pass callbacks that would allow your code to handle any errors that may arise after the db call is made as opposed to how it is ordinarily done using mongoose.
The Repository Pattern is a useful mechanism to abstract the mechanics of the data store away from the business logic. There are various ways of implementing a repository against a relational database, the mechanics could use plain old SQL or something more exotic like nHibernate or Entity Framework.
In most cases we need some abstraction what will give to us typical operations like CRUD (Create, Read, Update and Delete Operations). And Repository pattern will give to us this abstract Data Layer to interact with any database. Why Knex?
The first requirement of our repository is that it needs to connect to the mongoDB database, which can be implemented in the classes constructor. Within the constructor, the passed in object name and the database connection string are used to retrieve a connection to the database, that includes the specified objects collection.
If you working with Node.js you probably interact with the database (MongoDB, PostgreSQL, and etc) via ORM. But sometimes typical ORM does not cover our needs. For example, when we need to write nested queries with aggregation in PostgreSQL. Or when the performance of a generated query using ORM does not suit us.
I will explain two functionality of CRUD operation i.e. Create and Read and you will have the idea for rest. We will have the following layer:
Let first set up our model using mongoose schema. This is inside the test.model.js.
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var userSchema = new mongoose.Schema({
username: String,
password: String, //hash created from password
created_at: { type: Date, default: Date.now }
});
module.exports = mongoose.model("User", userSchema);
I will not explain how the controller will request a service layer for posting or receiving the data. It is just about calling a method from the service layer. So inside service layer, for sake of example say test.service.js. we will request repository layer like below. Provide the path for the repository and for your model as your folder structure.
const repository = require("../../models/repository");
var mongoose = require("mongoose");
var User = mongoose.model("User");
function createTestData(user1) {
return new Promise(function(resolve, reject) {
let user = new User(user1);// user1 is a object to be saved
repository
.create(user)
.then(data => {
resolve({
data: data
});
})
.catch(err => {
reject(err);
});
});
}
function listTestData() {
let params = {
limit: 10
};
return new Promise(function(resolve, reject) {
repository
.list(User, params)
.then(data => resolve(data))
.catch(err => reject(err));
});
}
Now we will create a repository so that every other service can call this repository for CRUD functionality. This will help to reduce boilerplate code.
function create(Model) {
return new Promise((resolve, reject) => {
Model.save(function(err, user) {
if (err) {
reject(err);
}
resolve(user);
});
});
}
function list(Model, queryParams) {
return new Promise((resolve, reject) => {
Model.find({})
.limit(parseInt(queryParams.limit))
.exec(function(err, data) {
if (err) reject(err);
resolve(data);
});
});
}
That's all. I have tried to explain as simple as possible. You may need to configure other settings like to connect to the database. But if you can make this work you can add other functionality to the repository.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With