Nội dung bài viết
Video học lập trình mỗi ngày
Expressjs giờ đây không còn quá xa lạ với những anh em làm web hay sử dụng expressjs rest api với môi trường node nữa rồi. Nhưng hẳn nhiều trường hợp trong khi làm rest api khi check data thì chỉ có anh em làm nhiều mới biết, null, length, underfined...
Nhưng ...
"Thật tình cờ, tình cờ biết đến nhau từ bao giờ" như ca sĩ hà oikio hát trong bài "nếu như" thì tình cờ tôi cố đi tìm cho mình một middleware để check data trước khi save dữ liệu xuống database thì vô tình đọc được một bài post "Three useful Express middleware" post by "zellwk.com' .
Bài viết liên quan tới express:
1 - async await error handling in express
2 - Ví dụ về NodeJS Session sử dụng Express Session
Nay tôi xin share lại và giải thích kỹ hơn về 3 middleware này. Trong đó tôi có làm một ví dụ đầy đủ về bài học này. Sau khi các bạn đọc xong thì có thể download code trên github về máy của mình. Nhớ đọc xong rồi mới lấy về.
Middleware morgan
Thật ra morgan thì hầu như bạn nào cũng sử dụng để ghi log rồi, và tôi cũng đã sử dụng từ lâu rồi chứ không phải tới bây giờ mới dùng. Hơn nữa do repush lại nên tôi cũng cần phải giải thích lại cho các bạn kỹ hơn. middleware morgan dùng để request logger. Nó cho bạn biết một số điều khi máy chủ của bạn nhận được yêu cầu. Và cho chúng ta nhiều thông tin hơn về client chẳng hạn như:
- Date
- HTTP version
- Method
- Referrer
- Remote
- Address
- Remote
- User
- Request header
- Response headers
- Response time
- Status code
- Url of the request
- User Agent
Morgan đi kèm với 5 format được xác định để ghi log trước để bạn lựa chọn:
- Combined
- Common
- Short
- Dev
- Tiny
Tương ứng với 5 định dạng khi chúng ta gọi http://localhost:3000 như trong ví dụ trên github:
Combined:
::1 - - [23/Nov/2019:09:45:16 +0000] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36 OPR/65.0.3467.48" ::1 - - [23/Nov/2019:09:45:16 +0000] "GET /favicon.ico HTTP/1.1" 404 150 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36 OPR/65.0.3467.48" ::1 - - [23/Nov/2019:09:45:16 +0000] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36 OPR/65.0.3467.48" ::1 - - [23/Nov/2019:09:45:16 +0000] "GET /favicon.ico HTTP/1.1" 404 150 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36 OPR/65.0.3467.48"
Common
::1 - - [23/Nov/2019:09:46:12 +0000] "GET / HTTP/1.1" 304 -
Short
::1 - GET / HTTP/1.1 304 - - 5.275 ms
Dev
GET / 304 4.764 ms - -
Tiny
GET / 304 - - 4.793 ms
Bổ sung thêm cho bài viết chính là Ngoài ra chúng ta có thể định nghĩa riêng của chúng ta thông qua cú pháp sau:
morgan(':method :url :status :res[content-length] - :response-time ms')
Cách sử dụng middleware morgan
const morgan = require('morgan'); app.use(morgan('tiny'))
như vậy là xong phần middleware morgan
Middleware camelcase-keys
camelcase-keys nhiệm vụ của middleware này là convert tất cả các thuộc tính trên form trước khi xống backend để get value.
Ví dụ : Trong form submit ta có
input name="first-name"
Thậm chí còn dev còn đặt name="First-Name" or "first_name", "first-name", or "FirstName". Nếu điều đó xảy ra thì ông nào làm rest api thì check mệt mỏi luôn, do đó camelcase-keys chính là một middleware để xử lý việc này:
Cách sử dụng middleware camelcase-keys
const camelcaseKeys = require('camelcase-keys') const camelcase = () => { return function (req, res, next) { req.body = camelcaseKeys(req.body, { deep: true }) req.params = camelcaseKeys(req.params) req.query = camelcaseKeys(req.query) next() } } app.use(camelcase())
Và cho dù ai có đặt name gì đi nữa thì về dưới backend chúng ta convert thành firstName
app.post('/example-camelcase', (req, res) => { console.log(req.body) res.status(200).json({elements: req.body.firstName}) })
Quá hay, ông nào nghĩ ta cái này hay hết :D
Cuối cùng là middleware omit-empty
ở bài viết gốc thì install omitEmpty nhưn tôi check thì nó bị falied. Có thể ông ghi sai Tập trung nè, nó có nhiệm vụ chỉ lấy giá trị tồn tại và đồng thời có giá trị ví dụ:
const object = { null: null, undefined: undefined, emptyString: '', emptyArray: [], emptyObject: {}, filled: 'yay' } console.log(omitEmpty(object)) // { // filled: 'yay' // nó chỉ lấy thằng này thôi // }
Điều đó giúp cho ta trong những trường hợp sau đây. Vì dụ trên form gửi xuống một array skills chẳng hạn:
fetch('/endpoint', { method: 'post', headers: { 'Content-Type': 'application/json' } body: JSON.stringify({ name: 'Zell', skills: ['coding', 'designing', 'writing'] }) }
Dưới thằng làm rest api đương nhiên phải check
if(skills.length){ //add database }
Đúng, chuẩn nhưng lỡ khi thằng nào nó ba gai nó thấy length = 0 thì nó không bỏ luôn nghĩa là :
fetch('/endpoint', { method: 'post', headers: { 'Content-Type': 'application/json' } body: JSON.stringify({ name: 'Zell' }) }
Nó chơi vậy, mình nhận được một error liền: "Cannot read property 'length' of undefined ". Rồi xong qua múc nó, xxx xxxxx bal blaaa... Để hoà giải trong trường hợp này thì omitEmpty là hữu ích, và tôi đánh giá nó rất hay
Cách sử dụng middlewware omit-empty
const omitEmpty = require('omit-empty') const removeEmptyProperties = () => { return function (req, res, next) { req.body = omitEmpty(req.body) req.params = omitEmpty(req.params) req.query = omitEmpty(req.query) next() } } app.use(removeEmptyProperties())
Lúc đó mình chỉ cần sử dụng nó như:
app.post('/example-omitempty', (req, res) => { const { skills } = req.body if (skills) { // Add skills to database return res.json('add database') } return res.json('skills not avaibale') })
Xong rồi đó, mấy ông chưa hiểu thì download source github để về check xem có đúng không. Với lại để áp dụng vào cho nó cool.
Repush: https://zellwk.com/blog/express-middlewares/