Preface
One of the most critical tasks when writing a backend code is to validate the input data passed by the clients. However, as I know, currently, there is no library for this purpose which is good enough to use.
Then, I decided to write one. I called it express-transformer.
The NPM document is well-prepared in terms of the API specification details. In this post, I will only introduce several use cases with sample codes, to share with you my motivation to write and publish this package.
Use cases
import {transformer} from 'express-transformer'
Check for a value existence
app.use(transformer('id').exists())
Customize the error message
app.use(transformer('id').exists().message('id is required'))
Convert the page
parameter in req.query
Convert the page
parameter in req.query
from string to number format, decrease the value by 1, ensure that the number is positive, and also set the default value 0
if it does not exist.
app.use(
transformer('page', {location: 'query'})
.defaultValue('1')
.toInt({min: 1})
.transform(page => page - 1)
)
Check password fields
app.use(
transformer('password')
.exists().message('password is required')
.isLength({min: 8}).message('password is too short'),
transformer(['password', 'passswordConfirm'])
.transform(([p, pc]) => {
if (p !== pc) throw new Error('dump string')
}, {validateOnly: true})
.message('Passwords do not match')
)
Convert user id to a user object, throw an error if not found.
transformer('id')
.exists()
.transform(async id => User.findById(id).exec())
.exists().message('User does not exist')
// in the next middleware, req.body.id is a non-null User object.
Array elements iteration
The following transformation chain iterates all values in req.body.messages[<index>].stars[<index>]
and carry out the transformation .toInt
.
transformer('user.messages[].stars[]')
.toInt({min: 0, max: 5})
More advanced cases with array iteration
This transformation chain iterate all available values at req.body.me.favorite[<index>]
, req.body.posts[<index>].meta.comments[<index>].likes[<index>]
, req.body.credits
, pairs them one by one and pass to the callback in .transform(callback)
.
transformer(['me.favorites[]', 'posts[].meta.comments[].likes[]', 'credits'])
.transform(([favorite, like, credits]) => {
// perform the check here
// because validateOnly is true, the returned value is ignored
}, {validateOnly: true})
Conclusion
Besides the above-mentioned validations, the library also supports various methods, such as:
.exists()
.is()
.isArray()
.isEmail()
.isIn(list)
-
.isLength()
(check string length or array's length) .matches(regex)
.defaultValue(value)
.toDate()
.toFloat()
.toInt()
.trim()
Please refer to the NPM package for more details.
Indeed, it is possible (and very easy) to add more methods via plugins. You can add your own methods, like: .isPostalCode()
, .isMongodbID()
, .isNewUsername
...
Top comments (0)