Tartalomjegyzék

< Érvényesség

Express - Sequelize beépített érvényesítés

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:

employee.js
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:

employeeController.js
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:

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