Validation trong Mongoose
Trong bài viết này chúng ta sẽ cùng nhau đi tìm hiểu về Validation tron Mongoose. Khi bạn làm việc với một Model, trước khi tiến hành thực hiện các mục đích chính của các Queries, mongoose sẽ có bước kiểm tra dữ liệu đầu vào, điều này là quan trọng trong quá trình làm việc bởi chỉ khi dữ liệu đúng với cấu trúc thì hệ thống mới hoạt động tốt.
1. Validation trong Mongoose là gì ?
Validation là một quá trình kiểm tra tính đúng đắn của dữ liệu, ví dụ như bạn chỉ có phép thuộc tính active
trong một document nào đó chỉ có kiểu là bolean
và không được phép thiếu. Validation sẽ thực hiện nhiệm vụ này.
Trước khi thực hiện các bước validation, mongoose có một vài lưu ý cho chúng ta:
- Quá trình validation phụ thuộc vafo SchemaType.
- Validation là một middleware, Mongoose thực thi middleware này như là
pre('save')
trong một schema một cách tự động. - Bạn có thể chạy validation bằng cách sử dụng
doc.validate(callback)
hoặcdoc.validationSync()
. - Quá trình validation không thực hiện trên các giá trị
undefined
, nó chỉ thực hiện khi bạn yêu cầu. - Validation là một đệ quy bất đồng bộ, khi bạn gọi
Modal.save(
), subdocument validation sẽ được thực thi, nếu xảy ra lỗiModel.save callback
sẽ trả về lỗi đó. - Bạn có thể tự điều chỉnh quá trình validation.
var schema = new Schema({ name: { type: String, required: true } }); var Cat = db.model('Cat', schema); // This cat has no name :( var cat = new Cat(); cat.save(function(error) { assert.equal(error.errors['name'].message, 'Path `name` is required.'); error = cat.validateSync(); assert.equal(error.errors['name'].message, 'Path `name` is required.'); });
2. Các validation có sẵn trong Mongoose
Mongoose xây dựng cho chúng ta một vài middleware validation có sẵn:
Bài viết này được đăng tại [free tuts .net]
- Đối với các kiểu Number thì bao gồm các trình kiểm tra như
min
,max
. - Đối với String thì bao gồm như :
enum
,match
,minglength
, vàmaxlength
,....
Ở ví dụ bên dưới chúng ta có một vài ví dụ về sử dụng các validator có sẵn trong Mongoose.
var breakfastSchema = new Schema({ eggs: { type: Number, min: [1, 'Phải ăn ít nhất 1 quả trứng nha !!'], max: 12 }, meat: { type: Number, required: [true, 'Phải ăn thịt nữa !!!'] }, drink: { type: String, enum: ['Coffee', 'Tea'], required: function() { return this.meat > 3; } } }); var Breakfast = db.model('Breakfast', breakfastSchema); var badBreakfast = new Breakfast({ eggs: 0, meat: 0, drink: 'Milk' }); badBreakfast.validateSync(); //Phải ăn ít nhất 1 quả trứng nha !! //Phải ăn thịt nữa !!! //`Milk` is not a valid enum value for path `drink`
3. Xây dựng một validation
Chúng ta có thể xây dựng một validation tùy chỉnh bằng cách thêm thuộc tính validate
vào object options Bạn có thể tìm thêm thông tin về cách xây dựng các hàm này bằng cách ttham khảo tài liệu về API validation. Ví dụ bên dưới là quá trình tự xây dựng một validation kiểm tra số điện thoại hợp lệ.
var userSchema = new Schema({ phone: { type: String, validate: { validator: function(v) { return /((09|03|07|08|05)+([0-9]{8})\b)/g.test(v) }, message: props => `${props.value} không phải là số điện thoại hợp lệ` }, required: [true, 'Vui lòng điền số điện thoại'] } }); var User = db.model('user', userSchema); var user = new User(); var error; user.phone = '09710104331'; error = user.validateSync(); assert.equal(error.errors['phone'].message, '0971010433 không phải là số điện thoại hơp lệ!'); user.phone = ''; error = user.validateSync(); assert.equal(error.errors['phone'].message, 'Yều cầu nhập số điện thoại'); user.phone = '0971010433'; //Đúng số điện thoại error = user.validateSync(); assert.equal(error, null);
4. Async Custom Validators
Khi thuộc tính validate() trả về một hàm bất đồng bộ (asynchronous function) thì chúng ta sẽ có 2 trường hợp:
- Nếu hàm validator của bạn trả về một promise (như là một async functon), mongoose sẽ đợi cho đến khi promise đó được thực thi hoàn tất.
- Nếu promise đó reject hoặc fullfill thì nó sẽ trả về
false
và đánh dấu quá trình vaidation đó lỗi.
const userSchema = new Schema({ name: { type: String, // Bạn có thể trả về một promise trong validate validate: () => Promise.reject(new Error('Oops!')) }, email: { type: String, // CÓ hai cách mà mongoose sẽ trả về lỗi // 1) Promise eject hoặc fullfill // 2) Nếu promise trả về false validate: { validator: () => Promise.resolve(false), message: 'Không thể xác minh email' } } }); const User = db.model('User', userSchema); const user = new User(); user.email = 'test@test.co'; user.name = 'test'; user.validate().catch(error => { assert.ok(error); assert.equal(error.errors['name'].message, 'Oops!'); assert.equal(error.errors['email'].message, 'Không thể xác minh emai'); });
Trên đây là những kiến thức cơ bản về Validation trong Mongoose. Mong bài viết này có thể giúp ích cho bạn cho việc lập trình với NodeJS, cảm ơn bạn đã quan tâm bài viết này.