How do you update the one-to-many relationship in Node.js?

I am working with a Node application that uses mongoose , mongodb and restify . I would like to know if it is good practice to have an import code from different models when defining a route function. This should be a fairly simple question, I just need a guide, and I can encode it myself. Thanks for taking the time to read this.

I know how to define a relationship, but I'm not sure how I should make an actual relationship. That is, in other words, when a car is created, what is the best way to add a car to it.

Please note that I am trying to keep this api RESTful.

I have two models that I would have to link based on the following schema, which is stored in db/schema.js :

 //schema.js var restify = require('restify'); var mongoose = require('mongoose'); var Schema = mongoose.Schema; var ObjectId = Schema.ObjectId; // User Schema exports.User = new Schema({ id: ObjectId, name: String, cars: [{ type: ObjectId, ref: 'Car' }], }); // Car Schema exports.Car = new Schema({ id: ObjectId, name: String, _user: { type: ObjectId, ref: 'User' }, }); 

Then I create models in models/... , where I have a different file for each model. Now each of them has only one line of code, but I left them as independent files when I need to write model methods.

In models/car.js :

  mongoose.model('Car', db_schema.Car); 

In models/user.js :

  mongoose.model('User', db_schema.User); 

And finally, I set up a route with a message and put the requests in routes/cars.js

This is not all, it is just necessary to answer my question.

  module.exports = function(app) { function putCar(req, res, next) { Car.findById(req.params.id, function (err, car) { if (!err) { car.name = req.params.name; car.save(function (err) { if (!err) { // PLACE A // current_user = get current user from session // current_user.cars.push(car); res.send(car); return next(); } else { return next(new restify.InternalError(err)); } }); } else { return next(new restify.MissingParameterError('ObjectId required.')); } }); } function postCar(req, res, next) { var car = new Car(req.params); car.save(function (err, car) { if (!err) { // PLACE B // current_user = get current user from session // current_user.cars.push(car); res.send(car); } else { return next(err); } }); } app.post('api/car', postCar); app.put('/api/car', putCar); } 

Would it be appropriate to have a code, such as pseudocode, in place A and place B? The problem that comes to my mind is that I need to require a User model in the routes / cars.js file, which makes things less modular. Would it be better to do this in / car.js models?

+4
source share
2 answers

I do not agree with the assumption that you need a circuit at all. I believe that 95% of the time when people use Mongoose, they really do not need it, because the advantages of having such a scheme simply do not outweigh the disadvantages of what people do with it. If there is some critical and unusual role that verifies that data objects are consistent with the schema in your application, maybe this is different. But in any case, you have to do this at the front end, and I just don't think that most systems really need to duplicate this effort differently at the back end.

In the vast majority of cases, databases are relatively small and simple. Your case is probably no exception. Therefore, let's actually take advantage of the fact that we have a schema database and lose the template.

It looks like you're planning on writing a ton of template code for each collection. Do not do this. Instead, take a look at some CRUD systems on Node as follows: https://github.com/AndrewRademacher/auto-crud Does MongoDB have its own REST interface? and / or you can add to them for your specific needs.

I think that part of this general philosophy that this business adds cars to the user object for this session at the back end is probably related to security. In other words, the assumption is that you cannot just take the front word for it and save the user object with any cars, because someone might try to hack into the interface. Again, for the vast majority of cases, I simply do not consider this a reasonable assumption.

I think it will be much easier if you have several general ways to do CRUD on the back panel and just add cars to the user data object on the front panel. And you can make fine-grained protection on the back panel on top of the common CRUD system if you really need to (that is, there is a reasonable business rationale, for example, something that affects the bottom line).

Basically, this material is a deterrence belief system, when almost all databases were SQL-based and had tight schemas with static languages ​​in the background, so you almost had to use a bunch of conflict code or rely on metaprogramming it was difficult with static languages.

I think that in 95% of cases when we have things like JSON and dynamic languages, it is wrong to have a bunch of a template that is simply differentiated by the entity and sometimes the field names.

+4
source

I would make two recommendations:

  • Report the function code in the route file to the controller for each of the other functions if you expect them to become relatively large.

  • Alternatively, you can create your own DAO wrappers (access databases) around each of the tables and then treat them as JavaScript objects instead of tables when making calls in a much simpler route file.

0
source

Source: https://habr.com/ru/post/1491364/


All Articles