[[oktatas:web:back-end_framework:express:ervenyesseg|< Érvényesség]]
====== Express - Sequelize beépített érvényesítés ======
* **Szerző:** Sallai András
* Copyright (c) 2025, Sallai András
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]]
* Web: https://szit.hu
===== Bevezetés =====
Az Sequelize rendelkezik beépített érvényesítéssel. Itt a Sequelize 6.x verzióhoz tartozó érvényességvizsgálatot nézzük át.
===== Model =====
Egy Employee model minimális id és name mezővel:
const Employee = sequelize.define('employee', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
}
})
Az "allowNull: false" azt határozza meg, hogy az adatbázisban a tábla mezője lehet null érték.
Ha viszont érvényességet szeretnénk vizsgálni, akár hibaüzenettel a valaidate: {} kulcsot kell
használni. Az érvényesség vizsgálat során a HTTP kérésben érkező kérésben szereplő adatokat vizsgáljuk.
A validate: {} értékén belül objektumokat vehetünk fel, vagyis újabb kulcs-éréték párok. Ilyen például, a **notNull** a body-ban érkező adatokra vonatkozik. A **notEmpty** azért kellhet, mert a notNull esetén még küldhető üres sztring. A notEmpty esetén nem. Nézzük meg **name** mező érvényességvizsgálatát.
const Employee = sequelize.define('employee', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notNull: { msg: 'A név mező kötelező' },
notEmpty: { msg: 'A név nem lehet üres sztring' }
}
}
})
Lássunk egy összetettebb kódot, ahol már több mező is szerepel, szabályos kifejezéssel is:
const { DataTypes } = require('sequelize')
const sequelize = require('../database/database')
const Employee = sequelize.define('employee', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notNull: { msg: 'A név mező kötelező' },
notEmpty: { msg: 'A név nem lehet üres sztring' }
}
},
city: {
type: DataTypes.STRING,
allowNull: true,
validate: {
is: {
args: /^[a-z]+$/i,
msg: 'Hiba! Csak betűk adhatók meg!'
}
}
},
salary: {
type: DataTypes.DOUBLE,
defaultValue: 300,
validate: {
isNumeric: {msg: 'Hiba! Csak szám adható meg!'}
}
},
birth: {
type: DataTypes.DATEONLY,
defaultValue: DataTypes.NOW,
validate: {
isDate: {msg: 'Hiba! Csak dátum!'}
}
}
})
sequelize.sync({
force: false
})
module.exports = Employee
===== Kontroller =====
Az érvényességet a modell-ben beállítottuk. Most nézzük egy példát, hogyan kezelhetjük
az érvénytelen eseteket.
A hibakezelő részben vizsgáljuk meg, hogy érvényességi hiba történt-e:
if(error instanceof Sequelize.ValidationError) {
res.status(400)
}else {
res.status(500)
}
Megvizsgáljuk, hogy az error objektum a Sequelize.ValidationError egy példánya? Ha igen,
akkor a kérés a hibás, ezért 400-as státuszkódot állítunk. Ha nem az érvényesség volt
a hiba, akkor valószínűleg szerver oldali hiba, ezért a státuszkód 500 lesz.
Lehetséges teljes kód:
const { Sequelize } = require('sequelize')
const Employee = require('../models/employee')
const EmployeeController = {
async index(req, res) {
try {
await EmployeeController.tryIndex(req, res)
} catch (error) {
res.status(500)
res.json({
success: false,
error: error.message
})
}
},
async tryIndex(req, res) {
const employees = await Employee.findAll()
const result = employees.map(emp => ({
id: emp.id,
name: emp.name,
city: emp.city,
salary: emp.salary,
birth: emp.birth
}))
res.json({
success: true,
data: result
})
},
async store(req, res) {
try {
await EmployeeController.tryStore(req, res)
} catch (error) {
if(error instanceof Sequelize.ValidationError) {
res.status(400)
}else {
res.status(500)
}
const errorMessage = error.errors[0].message
res.json({
access: false,
error: errorMessage
})
}
},
async tryStore(req, res) {
const employee = {
name: req.body.name,
city: req.body.city,
salary: req.body.salary,
birth: req.body.birth
}
const result = await Employee.create(employee)
res.status(201)
res.json({
succes: true,
data: result
})
}
}
module.exports = EmployeeController
A mintaprogramban a hibakezelés és a lényegi kód szét van választva, ezért látunk név függvényt:
* index()
* tryIndex()
* store()
* tryStore()
===== Beépített érvényesítők =====
A következő kódrészlet a Sequelize 6 verziójának beépített érvényesítőit mutatja:
sequelize.define('foo', {
bar: {
type: DataTypes.STRING,
validate: {
is: /^[a-z]+$/i, // RegEx egyezés
is: ["^[a-z]+$",'i'], // Mint a fenti, csak a RegEx karakterláncból áll
not: /^[a-z]+$/i, // RegEx nem egyezés
not: ["^[a-z]+$",'i'], // Mint a fenti, csak a RegEx karakterláncból áll
isEmail: true, // email cím (foo@bar.com)
isUrl: true, // URL elfogadása (https://foo.com)
isIP: true, // IPv4 (129.89.23.1) vagy IPv6 formátum
isIPv4: true, // IPv4 (129.89.23.1) cím
isIPv6: true, // IPv6 cím
isAlpha: true, // csak betűk az elfogadottak
isAlphanumeric: true, // betűk és számok; ez nem érvényes: "_abc"
isNumeric: true, // csak szám
isInt: true, // csak egész
isFloat: true, // csak valós szám
isDecimal: true, // csak szám
isLowercase: true, // csak kisbetűs
isUppercase: true, // csak nagybetűs
notNull: true, // a null nem megengedett
isNull: true, // csak null a megengedett
notEmpty: true, // nem lehet üres sztirng
equals: 'specific value', // csak a megadott érték lehet
contains: 'foo', // benne kell legyen ez a sztring rész
notIn: [['foo', 'bar']], // ezek az értékek nem lehetnek
isIn: [['foo', 'bar']], // csak ezek az értékek lehetnek
notContains: 'bar', // csak ha nem tartalmazza ezt rész sztringet
len: [2,10], // az érték hossza 2 és 10 között lehet
isUUID: 4, // csak uuid a megengedett
isDate: true, // csak dátum sztring lehet
isAfter: "2025-04-23", // csak az adott dátum után dátum
isBefore: "2025-04-23", // csak az adott dátum előtt dátum
max: 23, // az érték <= 23
min: 23, // az érétk >= 23
isCreditCard: true, // csak valós credit card számok
}
}
});
===== Saját érvényesítő =====
Készítünk egy érvényesítőt isAfterOrEqualToday néven, amihez egy névtelen függvényt rendelünk:
const YourModel = sequelize.define('YourModel', {
// ... egyéb mezők ...
startDate: {
type: DataTypes.DATE,
allowNull: true,
validate: {
isDate: true,
isAfterOrEqualToday: function(value) {
const today = new Date();
today.setHours(0, 0, 0, 0); // Mai nap éjfélkor
const startDate = new Date(value);
startDate.setHours(0, 0, 0, 0);
if (isNaN(startDate.getTime()) || startDate < today) {
throw new Error('A kezdő dátum nem lehet korábbi a mai napnál.');
}
},
},
},
// ... egyéb mezők ...
});
Ha nem érvényes a dátum, akkor kivételt dobunk.
===== Lásd még =====
* https://sequelize.org/docs/v6/core-concepts/validations-and-constraints/
* https://sequelize.org/docs/v7/models/validations-and-constraints/
* https://github.com/validatorjs/validator.js