Schema 유효성 검사
Schema 타입 & 속성 & 제약조건 알아보기
const mongoose = require("mongoose");
mongoose.set("strictQuery", true);
mongoose
.connect("mongodb://localhost:27017/shopApp")
.then(() => {
console.log("Connection Open");
})
.catch((e) => {
console.log("ERROR");
console.log(e);
});
const { Schema } = mongoose;
const productSchema = Schema({
name: {
type: String,
required: [true, "상품 이름이 필요합니다."],
},
price: {
type: Number,
required: true,
},
});
const Product = mongoose.model("Product", productSchema);
const bike = new Product({name: "Mountain Bike", price: 599 });
bike
.save()
.then((data) => {
console.log("It Worked!!!");
console.log(data);
})
.catch((err) => {
console.log("ERROR!!!");
console.log(err);
});
> node index.js
Connection Open
It Worked!!!
{
name: 'Mountain Bike',
price: 599,
_id: new ObjectId("63d65f2ce54108a157c08d14"),
__v: 0
}
Required
name
이 required : [ture, ...]
인데 model을 생성할때 생략한다면 오류 발생
...
const bike = new Product({ price: 599 });
...
> node index.js
ERROR!!!
Error: Product validation failed: name: 상품 이름이 필요합니다.
at ValidationError.inspect (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/error/validation.js:50:26)
at formatValue (node:internal/util/inspect:806:19)
at inspect (node:internal/util/inspect:365:10)
at formatWithOptionsInternal (node:internal/util/inspect:2273:40)
at formatWithOptions (node:internal/util/inspect:2135:10)
at console.value (node:internal/console/constructor:340:14)
at console.log (node:internal/console/constructor:377:61)
at /Users/users/Desktop/project/mongoose/index.js:45:13
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
errors: {
name: ValidatorError: 상품 이름이 필요합니다.
at validate (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/schematype.js:1346:13)
at SchemaType.doValidate (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/schematype.js:1330:7)
at /Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/document.js:2905:18
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
properties: [Object],
kind: 'required',
path: 'name',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'Product validation failed'
}
Connection Open
Type
price
가 type : Number
인데 String
타입을 입력한면 오류 발생
...
const bike = new Product({name: "Mountain Bike", price: "Hello World" });
...
> node index.js
ERROR!!!
Error: Product validation failed: price: Cast to Number failed for value "Hello World" (type string) at path "price"
at ValidationError.inspect (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/error/validation.js:50:26)
at formatValue (node:internal/util/inspect:806:19)
at inspect (node:internal/util/inspect:365:10)
at formatWithOptionsInternal (node:internal/util/inspect:2273:40)
at formatWithOptions (node:internal/util/inspect:2135:10)
at console.value (node:internal/console/constructor:340:14)
at console.log (node:internal/console/constructor:377:61)
at /Users/ryudonggyun/Desktop/code/mongoose/index.js:45:13
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
errors: {
price: CastError: Cast to Number failed for value "Hello World" (type string) at path "price"
at SchemaNumber.cast (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/schema/number.js:378:11)
at SchemaType.applySetters (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/schematype.js:1201:12)
at model.$set (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/document.js:1423:22)
at model.$set (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/document.js:1148:16)
at model.Document (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/document.js:166:12)
at model.Model (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/model.js:122:12)
at new model (/Users/users/Desktop/project/mongoose/ode_modules/mongoose/lib/model.js:5092:15)
at Object.<anonymous> (/Users/users/Desktop/project/mongoose/index.js:36:14)
at Module._compile (node:internal/modules/cjs/loader:1218:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1272:10) {
stringValue: '"Hello World"',
messageFormat: undefined,
kind: 'Number',
value: 'Hello World',
path: 'price',
reason: AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
assert.ok(!isNaN(val))
at castNumber (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/cast/number.js:27:10)
at SchemaNumber.cast (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/schema/number.js:376:12)
at SchemaType.applySetters (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/schematype.js:1201:12)
at model.$set (/Users/ryudonggyun/Desktop/code/mongoose/node_modules/mongoose/lib/document.js:1423:22)
at model.$set (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/document.js:1148:16)
at model.Document (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/document.js:166:12)
at model.Model (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/model.js:122:12)
at new model (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/model.js:5092:15)
at Object.<anonymous> (/Users/users/Desktop/project/mongoose/index.js:36:14)
at Module._compile (node:internal/modules/cjs/loader:1218:14) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
},
valueType: 'string'
}
},
_message: 'Product validation failed'
}
Connection Open
Schema에 정의하지 않은 정보 입력시
...
const bike = new Product({ name: "Mountain Bike", price: 599, color: "red" });
...
> node index.js
Connection Open
It Worked!!!
{
name: 'Mountain Bike',
price: 599,
_id: new ObjectId("63d6622ff897d692ffe7a2e8"),
__v: 0
}
Default
const productSchema = Schema({
name: {
type: String,
required: [true, "상품 이름이 필요합니다."],
},
price: {
type: Number,
required: true,
},
onSale: {
type: Boolean,
default: false,
},
});
...
const bike = new Product({ name: "Mountain Bike", price: 599});
...
> node index.js
Connection Open
It Worked!!!
{
name: 'Mountain Bike',
price: 599,
onSale: false,
_id: new ObjectId("63d664e0a32080265e9cf1a5"),
__v: 0
}
업데이트 유효성 검사하기
... Schema 수정
const productSchema = Schema({
name: {
type: String,
required: true,
maxlength: 20,
},
price: {
type: Number,
required: true,
min : 0,
},
onSale: {
type: Boolean,
default: false,
},
categories : [String],
qty : {
online: {
type: Number,
default: 0,
},
inStore: {
type: Number,
default: 0,
}
}
});
...
const bike = new Product({
name: "Tire Pump",
price: 19.5,
categories: ["Cycling"],
});
bike
.save()
.then((data) => {
console.log("It Worked!!!");
console.log(data);
})
.catch((err) => {
console.log("ERROR!!!");
console.log(err);
});
...
> node index.js
Connection Open
It Worked!!!
{
name: 'Tire Pump',
price: 19.5,
onSale: false,
categories: [ 'Cycling' ],
qty: { online: 0, inStore: 0 },
_id: new ObjectId("63d66ea2821c87ce860fe862"),
__v: 0
}
Product.findOneAndUpdate({ name: "Tire Pump" }, { price: 100 }, { new: true })
.then((data) => {
console.log("It Worked!!!");
console.log(data);
})
.catch((err) => {
console.log("ERROR!!!");
console.log(err);
});
> node index.js
Connection Open
It Worked!!!
{
qty: { online: 0, inStore: 0 },
_id: new ObjectId("63d66ea2821c87ce860fe862"),
name: 'Tire Pump',
price: 100,
onSale: false,
categories: [ 'Cycling' ],
__v: 0
}
price
의 min
값이 0
일때 음수로 업데이트 하기
Product.findOneAndUpdate(
{ name: "Tire Pump" },
{ price: -19.99 },
{ new: true }
)
.then((data) => {
console.log("It Worked!!!");
console.log(data);
})
.catch((err) => {
console.log("ERROR!!!");
console.log(err);
});
price
의 min
값이 0
일때 음수로 업데이트 결과
> node index.js
Connection Open
It Worked!!!
{
qty: { online: 0, inStore: 0 },
_id: new ObjectId("63d66ea2821c87ce860fe862"),
name: 'Tire Pump',
price: -19.99,
onSale: false,
categories: [ 'Cycling' ],
__v: 0
}
- 유효성 검사의 의미가 없이 음수로 나온다.
- 무엇인가 만들면 유효성 검사가 자동으로 적용되는데 업데이트 이후에는 Mongoose에게 직접 유효성 검사를 적용하라고 명령해야한다.
runValidators: true
Product.findOneAndUpdate(
{ name: "Tire Pump" },
{ price: -19.99 },
{ new: true, runValidators: true }
)
.then((data) => {
console.log("It Worked!!!");
console.log(data);
})
.catch((err) => {
console.log("ERROR!!!");
console.log(err);
});
runValidators: true
result
유효성 검사 결과 Error
> node index.js
ERROR!!!
Error: Validation failed: price: Path `price` (-19.99) is less than minimum allowed value (0).
at ValidationError.inspect (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/error/validation.js:50:26)
at formatValue (node:internal/util/inspect:806:19)
at inspect (node:internal/util/inspect:365:10)
at formatWithOptionsInternal (node:internal/util/inspect:2273:40)
at formatWithOptions (node:internal/util/inspect:2135:10)
at console.value (node:internal/console/constructor:340:14)
at console.log (node:internal/console/constructor:377:61)
at /Users/users/Desktop/project/mongoose/index.js:79:13
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
errors: {
price: ValidatorError: Path `price` (-19.99) is less than minimum allowed value (0).
at validate (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/schematype.js:1346:13)
at SchemaType.doValidate (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/schematype.js:1330:7)
at /Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/helpers/updateValidators.js:151:22
at module.exports (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/helpers/updateValidators.js:202:7)
at /Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/query.js:4330:9
at promiseOrCallback (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/helpers/promiseOrCallback.js:11:14)
at model.Query.validate (/Users/users/Desktop/project/mongoose/node_modules/mongoose/lib/query.js:4325:10)
at /Users/users/Desktop/project/mongoose/node_modules/kareem/index.js:497:25
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
properties: [Object],
kind: 'min',
path: 'price',
value: -19.99,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'Validation failed'
}
Connection Open