Hi Fernando,
I agree that adding a global filter data like companyId in each controller would be error-prone and insecure. I like your approach - a middleware which "prepares" models.
I would do some very small changes:
1. I wouldn't directly modify the prototype in the middleware, but create a new model instance:
2. In model there are two classes: Model responsible for fetching/persisting data and a pure Project class to store data:
classProject{constructor({id,companyId,name}){this.id=id;this.companyId=companyId;this.name=name;}}classProjectModel{constructor(companyId){this.companyId=companyId;}find(){returnPROJECTSDATA.filter(project=>project.companyId===this.companyId).map(projectData=>newProject(projectData));}// here other methods...}module.exports=ProjectModel;
I like your idea! I wasn't sure about modifying the prototype in the middleware, I like your approach, but I think it has to be a better approach because now the static methods are in ProjectModel and the instance methods will be in Project.
I think we can export the model like this:
module.exports=(context)=>{classProject{// constructor// static and instance methods}Project.prototype._context=context;Project._context=context;}
This allows us not to modify the prototype from the middleware and do it in the model. It also binds the whole context to the model, this can be important as we could have more things in the context like a logger or any other function that requires the request context.
We could also take advantage of the closures and do something like
module.exports=(context)=>{classProject{// constructorfind(){constcompanyId=context.user.company;// search in the database by companyId}}Project.prototype._context=context;Project._context=context;}
With this approach, the methods are more elegant but we can't split the model into different files.
Hi Fernando,
I agree that adding a global filter data like companyId in each controller would be error-prone and insecure. I like your approach - a middleware which "prepares" models.
I would do some very small changes:
1. I wouldn't directly modify the prototype in the middleware, but create a new model instance:
2. In model there are two classes: Model responsible for fetching/persisting data and a pure Project class to store data:
What do you think?
Hi Kryz! thanks for your comment!
I like your idea! I wasn't sure about modifying the prototype in the middleware, I like your approach, but I think it has to be a better approach because now the static methods are in
ProjectModel
and the instance methods will be inProject
.I think we can export the model like this:
This allows us not to modify the prototype from the middleware and do it in the model. It also binds the whole context to the model, this can be important as we could have more things in the context like a
logger
or any other function that requires the request context.We could also take advantage of the closures and do something like
With this approach, the methods are more elegant but we can't split the model into different files.
What do you think?
Thank you for your answer!
Hi,
I like your idea!
One more thing - the middleware runs the factory on each request, is it good for the application performance?
Maybe it would be better to delay this calls, for example:
and in the controller something like this:
I know, it doesn't look nice, I'm sure there is a better solution..