3 middleware hữu ích khi sử dụng express rest api

3 middleware hữu ích khi sử dụng express rest api

·

4 min read

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ư:

  1. Date

  2. HTTP version

  3. Method

  4. Referrer

  5. Remote

  6. Address

  7. Remote

  8. User

  9. Request header

  10. Response headers

  11. Response time

  12. Status code

  13. Url of the request

  14. User Agent

Morgan đi kèm với 5 format được xác định để ghi log trước để bạn lựa chọn:

  1. Combined

  2. Common

  3. Short

  4. Dev

  5. 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/