Middleware trong NodeJS


Các bài trước chúng ta đã đụng đến middleware, nhưng chưa tìm hiểu nó hoạt động như thế nào. Bây giờ mình sẽ đi sâu một xíu về thằng này để các bạn hiểu rõ hơn.

Giới thiệu

Middleware là những đoạn mã trung gian nằm giữa các requestresponse. Nó nhận các request, thi hành các mệnh lệnh tương ứng trên request đó. Sau khi hoàn thành nó response (trả về) hoặc chuyển kết quả ủy thác cho một Middleware khác trong hàng đợi.
Nói đơn giản nó như những bộ lọc requestresponse,

ExpressJS khi hoạt động, cơ bản là một loạt các hàm Middleware được thực hiện liên tiếp nhau.
Sau khi đã thiết lập, các request từ phía người dùng khi gửi lên server sẽ lần lượt thực hiện qua các hàm Middleware cho đến khi trả về response cho người dùng ( kết thúc 1 request ). Các hàm này sẽ được quyền truy cập đến các đối tượng Request ObjectResponse Object, hàm Middleware tiếp theo next và đối tượng lỗi err nếu cần thiết.

Một hàm Middleware sau khi hoạt động xong, nếu chưa phải là cuối cùng trong danh sách các hàm cần thực hiện, sẽ phải gọi lệnh next() để chuyển sang Middleware tiếp theo, nếu không Request sẽ bị treo tại đó.

Các chức năng mà middleware có thể thực hiện:

  • Thực hiện ở bất cứ đâu
  • Thay đổi đối tượng request và response
  • Kết thúc một quá trình request / response
  • Gọi hàm middleware tiếp theo trong stack

Trong Express có thể sử dụng các kiểu middleware sau:

Application-level middleware

Khi khởi tạo một Web Application với ExpressJS, chúng ta sẽ có đối tượng đại diện cho Web App đó, ở đây gọi là app. Đối tượng này có thể khai báo các Middleware thông qua các hàm: app.use() hoặc app.METHOD (METHOD sẽ là các kiểu HTTP Method được Express hỗ trợ, ví dụ: app.get(), app.post(), … ).

Ví dụ dưới đây mô tả một hàm ko khai báo đường dẫn cụ thể, do đó nó sẽ được thực hiện mỗi lần request:

var app = express()

app.use(function (req, res, next) {
  console.log('Nguyen Quang Dat')
  next()
})

Ví dụ dưới đây dùng hàm use đến đường dẫn /user/:id. Hàm này sẽ được thực hiện mỗi khi request đến đường dẫn /user/:id bất kể phương thức nào (GET, POST,…):

app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
})

Tiếp theo là một ví dụ cho hàm được thực hiện mỗi khi truy cập đến đường dẫn /user/:id bằng phương thức GET:

app.get('/user/:id', function (req, res, next) {
  res.send('USER')
})

Khi muốn gọi một loạt hàm middleware cho một đường dẫn cụ thể, chúng ta có thể thực hiện như ví dụ dưới đây, bằng cách khai báo liên tiếp các tham số là các hàm sau tham số đường dẫn :

app.use('/user/:id', function (req, res, next) {
  console.log('Request URL:', req.originalUrl)
  next()
}, function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
})

Router-level middleware

Các middleware này về chức năng không khác gì so với application-level middlewware ở trên, tuy nhiên thay vì dùng biến app có thể gây nhầm lẫn với các thiết lập, phần router có thể không rõ ràng và khó phân biệt, ExpressJS cung cấp một đối tượng router chuyên dùng để khai báo route bằng cách gọi hàm sau:

var app = express()
var router = express.Router()

router.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})

router.get('/user/:id', function (req, res, next) {
  console.log(req.params.id)
  res.render('special')
})

app.use('/', router)

Error-handling middleware

Đây là các middleware phục vụ cho việc xử lý lỗi.
Một lưu ý là các hàm cho việc này luôn nhận bốn tham số (err, req, res, next). Khi muốn khai báo một middlware cho việc xử lý lỗi, bạn cần tạo một hàm có 4 tham số đầu vào. Mặc dù bạn có thể không cần sử dụng đối tượng next, nhưng hàm vẫn cần format với bốn tham số như vậy. Nếu không ExpressJS sẽ không thể xác định đó là hàm xử lý lỗi, và sẽ không chạy khi có lỗi xảy ra, chỉ hoạt động giống như các hàm middlware khác.

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

Built-in middleware

Third-party middleware

Sử dụng Third-party sẽ giúp chúng ta thêm các chức năng cho Web App của mình mà không cần mất nhiều công implement.

Chúng ta sẽ cần cài đặt module thông qua npm, sau đó khai báo sử dụng trong đối tượng app nếu dùng ở Application-level, hoặc qua đối tượng router nếu dùng ở Router-level.

Chúng ta sử dụng những middleware đã được xây dựng sẵn, phục vụ cho một số tính năng nào đó. Chúng ta chỉ cần khai báo vào.
Các bạn có thể theo dõi thêm Tại đây

Mình sẽ ví dụ vài đặt và sử dụng một middleware có tên là body-parser, dùng để đọc data người dùng post lên.

npm install body-parser
var express = require('express')
var app = express()
var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({ extended: true }));

Các bạn có thể sử dụng middleware này phục vụ cho việc phân quyền, cấp quyền cho user cũng như admin.

Kết luận

Mình vừa chia sẻ một số kiến thức khi làm việc với middleware.

Nguồn tham khảo:

Rất mong được sự ủng hộ của mọi người để mình có động lực ra những bài viết tiếp theo.
{\__/}
( ~.~ )
/ > ♥️ I LOVE YOU 3000

JUST DO IT!


Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Nguyễn Quang Đạt !
Comments
  TOC