我们知道mongoose为我们提供了一种简单的验证方法。但是假设您正在使用express + mongoose来构建微服务;一些客户(可能是网络应用程序,移动应用程序等)需要消费它。
通常,我更喜欢用简单的错误代码和消息来回复JSON。在大多数情况下,客户可以根据他们向用户显示的语言创建自己的消息。
默认情况下,如果我们从mongoose捕获错误,我们可以获得JSON响应,例如:
{
"errors": {
"price": {
"message": "Path `price` (-1) is less than minimum allowed value (0).",
"name": "ValidatorError",
"properties": {
"min": 0,
"type": "min",
"message": "Path `{PATH}` ({VALUE}) is less than minimum allowed value (0).",
"path": "price",
"value": -1
},
"kind": "min",
"path": "price",
"value": -1,
"$isValidatorError": true
},
"code": {
"message": "Product with given code already exists",
"name": "ValidatorError",
"properties": {
"type": "user defined",
"message": "Product with given code already exists",
"path": "code",
"value": "p-1000"
},
"kind": "user defined",
"path": "code",
"value": "p-1000",
"$isValidatorError": true
}
},
"_message": "Product validation failed",
"message": "Product validation failed: price: Path `price` (-1) is less than minimum allowed value (0)., code: Product with given code already exists",
"name": "ValidationError"
}
exports.createOne = async(function* list(req, res) {
try {
const product = new Product(req.body)
const newProduct = yield product.save()
res.json(newProduct)
} catch (err) {
res.status(400).json(err)
}
})
const mongoose = require('mongoose')
const Schama = mongoose.Schema
const minlength = [5, 'The value of `{PATH}` (`{VALUE}`) is shorter than the minimum allowed length ({MINLENGTH}).'];
const ProductSchema = new Schama({
code: { type: String, required: true, minlength, index: true, unique: true, trim: true, lowercase: true },
name: { type: String, required: true, trim: true },
price: { type: Number, required: true, min: 0, max: 100000 },
categories: [String],
})
ProductSchema.path('code').validate(function uniqueEmail(code, fn) {
const Product = mongoose.model('Product')
// Check only when it is a new Product or when code field is modified
if (this.isNew || this.isModified('code')) {
Product.find({ code }).exec((err, products) => {
fn(!err && products.length === 0)
})
} else fn(true)
}, 'Product with given code already exists')
ProductSchema.statics = {
/**
* List products
*
* @param {Object} options
* @api private
*/
pageList: function pageList(conditions, index, size) {
const criteria = conditions || {}
const page = index || 0
const limit = size || 30
return this.find(criteria)
.populate('user', 'name username')
.sort({ createdAt: -1 })
.limit(limit)
.skip(limit * page)
.exec()
},
}
mongoose.model('Product', ProductSchema)
我正在尝试包装错误消息,以使其对消费者来说很简单。 它可能像:
{
"errors": [
{
"message": "Path `price` (-1) is less than minimum allowed value (0).",
"code": "100020"
},
{
"message": "Product with given code already exists",
"code": "100021"
}
],
"success": false
}
将在api文档上维护代码和相应的消息。该消息通常对于消费者理解代码是有用的,并且消费者(例如web客户端)可以根据代码创建他们自己的消息,例如法国消息并向最终用户显示。
如何利用mongoose的valiation来实现这一目标?也许我可以循环erros的属性并使用${path}-${kind}
组合代码。
我知道在大多数情况下,客户端应该在调用apis之前进行验证。但必须有一些情况下,API必须抛出错误。
对此有何想法?