[[:oktatas:web:back-end_framework:express|< Express]]
====== Express - Sequelize modellek ES ======
* **Szerző:** Sallai András
* Copyright (c) 2025, Sallai András
* Szerkesztve: 2025
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]]
* Web: https://szit.hu
===== A Sequalize =====
A Sequelize egy TypeScript és NodeJS alapú ORM a következő adatbázis rendszerek számára:
* Oracle
* Postres
* MySQL
* MariaDB
* SQLite
* SQL Server
* stb.
Webhely:
* https://sequelize.org/ (2025)
Ebben a Sequelize-t a lehető legegyszerűbben használjuk. Nem használunk migrációt, feltöltőt (seeder). Migráció helyett, a modellen futtatható sync() függvényt használjuk, ami automatikusan létrehozza a modellben megadott táblát, és a későbbiekben is szinkronizálja. A táblák a szerver induláskor azonnal létrejönnek.
===== Projket =====
npm init -y
npm install express
===== Projekt könyvtárszerkezet =====
empapi/
|-app/
| |-controllers/
| |-database/
| |-models/
| |-routes/
| `-indexjs
|-node_modules/
|-tools/
|-.env
|-.env.example
|.package.json
`-pnpm-lock.yaml
===== Függőségek telepítése =====
npm install sequelize mariadb sqlite3 dotenv morgan
npm install --save-dev nodemon
===== Környezet =====
Feltételezzük, hogy van (vagy lesz) egy emp nevű adatbázis, egy emp nevű felhasználóval, aki a "titok" jelszóval éri el az adatbázist.
A beállításokat az .env fájlban végezzük, ami alapértelmezetten a projekt gyökérkönyvtárba szokás tenni.
APP_PORT=8000
DB_DIALECT=mariadb
DB_HOST=127.0.0.1
DB_NAME=emp
DB_USER=emp
DB_PASS=titok
# DB_STORAGE=/ut/vonal
A DB_DIALECT lehetséges értékei esetünkben:
* mariadb
* sqlite
A DB_STORAGE értéke Sqlite esetén szükséges:
* útvonal /ut/vonal
* :memory:
A :memory: csak sqlite dialaktus mellett állítható be, és azt jelenti, az adatbázis a memóriában van, az alkalmazás újraindításával törlődik.
A .env.example néven célszerű egy kezdetleges beállítófájlt létrehozni.
===== Adatbázis =====
MySQL vagy MariaDB adatbázisban hozzuk létre az adatbázist és a hozzátartozó felhasználót.
create database emp
character set utf8
collate utf8_hungarian_ci;
grant all privileges
on emp.*
to emp@localhost
identified by 'titok';
A táblák automatikusan létrejönnek a sequelize.sync() függvény hívás hatására az emplyoee.js fájlban.
===== MariaDB adatbázis elérése =====
A többféle adatbázist használunk, azt is elég egyetlen fájlban megadni. Itt most csak MariaDB adatbázist használunk, ezért a nevet is **database.js** lett.
const Sequelize = require('sequelize')
require('dotenv').config()
const sequelize = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASS,
{
host: process.env.DB_HOST,
dialect: process.env.DB_DIALECT,
storage: process.env.DB_STORAGE,
dialectOptions: {}
}
)
module.exports = sequelize
A process.env.DB kezdetű sorok, az adatokat a .env fájlból olvassák.
===== Model definiálása =====
import { DataTypes } from 'sequelize'
import sequelize from '../database/database.js'
const Employee = sequelize.define('employees', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: { type: DataTypes.STRING },
city: { type: DataTypes.STRING },
salary: { type: DataTypes.DOUBLE }
})
await sequelize.sync({
force: false
})
export default Employee
A "nem erőltetve" annyit jelent, hogy új mezők létrejönnek, de meglévőket nem írja felül. Igény szerint a felülírás is kikényszeríthető a force: true értékkel.
Egyéb típusok:
^ Jelölés ^ Jelentés ^
| DataTypes.INTEGER | egész |
| DataTypes.STRING | sztring |
| DataTypes.DATE | Dátum és idő |
| DataTypes.DOUBLE | Double |
| DataTypes.FLOAT | Float |
| DataTypes.DECIMAL | Decimális |
| DataTypes.BOOLEAN | TINYINT(1) |
Az itt megadott típusok nem az összes használható típus, csak néhány általánosan használt került ide. A következő linkeken találunk még használható típusokat:
* https://sequelize.org/docs/v6/core-concepts/model-basics/ (2023)
* https://sequelize.org/docs/v6/other-topics/other-data-types/ (2023)
==== A modell tesztelése ====
// A létrehozott modell után, a modellfájlban:
await Employee.sync()
await Employee.create({
name: 'Erős István',
city: 'Szeged',
salary: 492
})
Ha kiegészítjük a modellünket a két utasítással, akkor a sync() hívás
hatására létre kell jöjjön az adatbázisban az employees táblának.
A create() függvény hatására létre kell jönnie egy rekordnak a
megadott tartalommal.
===== Kontroller =====
Az employeecontroller.js állományban hozzuk létre az EmployeeController-t, ami négy függvényt tartalmaz: index(), store(), update() és destroy().
import Employee from '../models/employee.js'
const EmployeeController = {
async index(req, res) {
try {
const employees = await Employee.findAll()
res.json(employees)
} catch (error) {
res.status(500).json({ error: error.message })
}
},
async create(req, res) {
try {
const employee = await Employee.create(req.body)
res.status(201).json(employee)
} catch (error) {
res.status(500).json({ error: error.message })
}
},
async update(req, res) {
try {
const employee = await Employee.findByPk(req.params.id)
if (!employee) {
return res.status(404).json({ error: 'Employee not found' })
}
await employee.update(req.body)
res.json(employee)
} catch (error) {
res.status(500).json({ error: error.message })
}
},
async delete(req, res) {
try {
const employee = await Employee.findByPk(req.params.id)
if (!employee) {
return res.status(404).json({ error: 'Employee not found' })
}
await employee.destroy()
res.json({ message: 'Employee deleted successfully' })
} catch (error) {
res.status(500).json({ error: error.message })
}
}
}
export default EmployeeController
A példában a minden függvényben try...catch szerkezetben valósítjuk meg a kérések feldolgozását és a válaszokat. Ezeket a kivételkezeléseket érdemes külön függvényekbe szervezni.
===== Routing =====
Az útválasztó rész, jelenleg négy útvonalat tartalmaz, négy különböző metódussal. Az útválasztáshoz az express útválasztó objektumát használjuk.
import Router from 'express'
const router = Router()
import EmployeeController from '../controllers/employeecontroller.js'
router.get('/employees', EmployeeController.index)
router.post('/employees', EmployeeController.create)
router.put('/employees/:id', EmployeeController.update)
router.delete('/employees/:id', EmployeeController.delete)
export default router
===== Belépési pont =====
Az alkalmazás belépési pontja az index.js fájl, amiben az express biztosítja a szerver indulását. Itt vesszük használatba a routes/api.js fájlban készült útválasztó információkat is.
import express from 'express'
const app = express()
import router from './routes/api.js'
import morgan from 'morgan'
import dotenv from 'dotenv'
dotenv.config()
app.use(morgan('dev'))
app.use(express.json())
app.use(router)
const PORT=process.env.APP_PORT || 8000
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
A **.env** olvasásához szükség van a **dotenv** csomag beépítésére, a naplózáshoz a **morgan** csomagot használjuk.
A process.env.APP_PORT a .env fájlból olvassa az alkalmazás által használandó portot.
===== A package.json =====
{
"name": "simpleapi",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "nodemon app --watch app"
},
"dependencies": {
"dotenv": "^17.2.1",
"express": "^5.1.0",
"mariadb": "^3.4.5",
"morgan": "^1.10.1",
"sequelize": "^6.37.7"
},
"devDependencies": {
"nodemon": "^2.0.22"
}
}
===== Futtatás =====
npm start
===== Teszt =====
A resen paranccsal:
res localhost:8000/api/employees
===== Linkek =====
* https://github.com/vaclav18/express-api-mariadb (2023)