Hỏi về cách access req của Expressjs trong Mongoosejs

Hi mọi người,
Mình mới tìm hiểu về Nodejs/Expressjs và xài Mongoosejs để thao tác với database.
Có một vướng mắc mà mình lục tung cả cái Google cũng không có câu trả lời.

Trong tất cả các collection đều có trường created_by để lưu người thao tác với mỗi document.

created_by này được gán tự động trong pre middleware của Mongoose, nhưng mình không biết làm cách nào để truy cập vào request parameter để lấy thông tin user. Mình dùng Passportjs, nó sẽ lưu thông tin user ở req.user

Mọi người đóng góp ý kiến ạ, thanks.

Câu hỏi của em hơi khó hiểu,

  • Data lưu ở Server rồi thì cứ find ra mà dung.
  • Còn muốn lấy Data ở request thì truy xuất vào mà lấy .
1 Like

Dạ, ý em là làm thế nào để access đến cái request object của Express trong mấy cái middleware của Mongoose. Ví dụ find các document của user hiện tại, thì em tạo một pre find middleware để tự động thêm where:

schema.pre('find', function(next){
    this.where({user: req.user.id}); // req object của Express.
    next();
});

Hiện tại em phải lưu các thông tin request trong một biến global để có thể dùng bất kỳ đâu. Nhưng cách đó không phải là best practice:

// `app.js`:
...
const globalRequest = require('./global/request');

app.use(function(req, res, next){
    globalRequest.setRequest(req); // Gán req vào global.
    next();
});
...

// `globals/request.js:
var _req;

 exports.setRequest = (req) => {
    _req = req;
 }

 exports.getRequest = () => {
     return _req;
 }

 exports.unsetRequest = () => {
     _req = undefined;
 }

Và sử dụng trong Mongoose:

...
const globalRequest = require('./global/request');

schema.pre('find', function(next){
    this.where({user: globalRequest.getRequest().user.id});
    next();
});
...

Lúc bắt đầu run server, thì bạn khởi tạo biến toàn cục đại diện cho Mongoose.
Khởi tạo xong thì mới thiết lập express, route.
Với mỗi route thì biến toàn cục của Mongoose xử lý.

Web Framework bên PHP hay ngôn ngữ khác, việc setup này framework làm sẵn cho mình, công việc của mình chỉ cần sửa các file config. Còn ExpressJS thì chỉ chuyên về xử lý HTTP Request và Response, nên việc thiết lập phải làm thủ công.

1 Like

Mình có biến toàn cục cho Mongoose rồi bạn.
Nhưng cái mình muốn là làm sao access request object của Express trong middleware của Mongoose.

Middleware của Mongoose thì chỉ thao tác cho Mongoose thôi. Middleware của Model truy xuất đến request của Express nằm ngoài tầm của Mongoose. Nên cách sử dụng middleware mình thấy không hợp lý.

1 Like

Nếu nó không thể lấy thông tin từ bên ngoài thì nó dùng để làm gì, không lẽ chỉ xài tĩnh?

this.where({user: 12}) // ???

bên PHP, Laravel FW có hàm request() xài khắp nơi mà

“Không hợp lý”, không phải là “không thể”. Trong 1 middleware bạn vẫn có thể gọi các hàm và truy xuất biến ngoài phạm vi của nó.

Đúng là Laravel có hỗ trợ các static proxy như request(), nhưng mình cũng không dùng nó trong Model. Vì Model là nơi xử lý dữ liệu, nên không có tác vụ liên quan gì đến Route cả.

1 Like

Bạn có cách nào thì giúp mình với, mình tạm thời bỏ qua việc nó hợp lý hay không.

Bởi vì mình cần lấy thông tin user hiện tại được lưu trong request object của Express.

Mình không thể viết lệnh where({user: req.user.id}) thẳng trong route vì mình dùng cả populate của Mongoose. thằng populate này nó sẽ find không giới hạn một user nào.

Đó là lý do mình cần dùng đến Mongoose middleware để tự động chỉ lấy các document của user hiện tại.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?