A Sequelize egy ORM, azaz Object-Relational Mapping, magyarul Objektum-relációs leképző eszköz.
Ebben a leírásban Sequelize, Express, Sqlite3 és Nodemon-t használjuk az alkalmazás létrehozására.
A fejlesztés során használjuk a sequelize-cli parancsot. Ennek dokumentációja itt található:
A Sequelize weboldala:
A Sequelize biztosítja az adatbázis elérést.
mkdir app01 cd app01 git init
A projekt függőségeinek telepítése:
npm init -y npm install sequelize sqlite3 npm install --save-dev sequelize-cli
További függőség:
npm install express nodemon
MariaDB/MySQL esetén:
npm install mysql2
Vagy:
npm install mariadb
Ha nem készítünk .sequelize fájlt, akkor a következő könyvtárszerkezet jön létre:
app01/ |-config/ | `-config.json |-migrations/ |-models/ | `-index.js |-node_modules/ |-seeders/ |-package-lock.json `-package.json
Készítsünk a sequelize-cli számára egy beállítást, a .sequelizerc fájlban:
const path = require('path'); module.exports = { 'models-path': path.resolve('app', 'models'), 'seeders-path': path.resolve('database', 'seeders'), 'migrations-path': path.resolve('database', 'migrations') };
A modelleket az app könyvtáron belül fogjuk elhelyezni, a seeder és migrations eszközöket a database könyvtárban.
Az src könyvtárba kerül minden forrásfájl.
const path = require('path'); module.exports = { 'config': path.resolve('src', 'config', 'database.json'), 'models-path': path.resolve('src', 'models'), 'seeders-path': path.resolve('src', 'database', 'seeders'), 'migrations-path': path.resolve('src', 'database', 'migrations') };
npx sequelize-cli init
Ha például az app könyvtárat választottuk, a következő könyvtárak jönnek létre:
app01/ |-app/ | `-models/ | `-index.js |-config/ `-database/ |-migrations/ `-seeders/
Futtassuk a következő parancsot:
echo " node_modules/ .DS_Store .env" >> .gitignore
A .gitignore állomány tartalma, a parancs futtatása után:
node_modules/ .DS_Store .env
NODE_ENV=development PORT=8000
{ "development": { "dialect": "sqlite", "storage": "./database.sqlite" }, "test": { "dialect": "sqlite", "storage": "memory" }, "production": { "dialect": "sqlite", "storage": "./database.sqlite" } }
Készítünk egy modellt, amit használunk majd a programban, és egy migrációs fájlt ami alapján létrehozzuk az adatbázis tábláit.
A modell nevét egyesszámban adjuk meg. A migrálás során az adatbázisban a tábla többesszámban jön létre, az első betű nagybetű lesz.
npx sequelize-cli model:generate --name Employee --attributes name:string,city:string,salary:decimal
Ha újra szeretnék gyártani, akkor a végére:
--force
A migrációs fájlt nem írja, mindig új jön létre.
A database.sqlite fájl a migrálás során jön létre.
npx sequelize db:migrate
Ha szükséges a migráció visszavonható:
npx sequelize db:migrate:undo
Üres migrációs állományt is létrehozhatunk:
npx sequelize-cli migration:create --name valami
A Sequelize mellett Express-t használjuk.
Telepítés:
npm install express
Létrehozok egy controllers könyvtárat:
mkdir api/controllers
A gyökérkönyvtárban létrehozok egy server.js fájlt:
const express = require('express'); const bodyParser = require('body-parser'); const PORT = process.env.PORT || 3000; const app = express(); app.use(express.json()) require('./routes/index')(app); app.use(bodyParser.json()) app.listen(PORT, () => console.log(`Listening on port: ${PORT}`)) module.exports = app
module.exports = app => { const router = require('express').Router() router.get('/', (req, res) => { res.json({messge: 'Dolgozók REST API'}) }) app.use('/api', router) }
Telepítsük a nodemon programot:
npm install nodemon --save-dev
Használjuk a package.json fájlban:
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "nodemon server.js" }
Indítás:
npm start
Nézzük meg az eredményt:
http://localhost:3000/api
Vegyük fel a server.js fájlban:
require('./routes/employee.routes')(app);
A teljes kód:
const express = require('express'); const bodyParser = require('body-parser'); const PORT = process.env.PORT || 3000; const app = express(); app.use(express.json()) require('./routes/index')(app); require('./routes/employees.routes')(app); app.use(bodyParser.json()) app.listen(PORT, () => console.log(`Listening on port: ${PORT}`)) module.exports = app
Hozzuk létre routingot a routes könyvtrában, employees.routes.js fájlban:
module.exports = app => { const router = require('express').Router() router.get('/', (req, res) => { res.send('get kérés'); }) app.use('/api/employees', router) }
Cseréljük ki a routing bejegyzést, hogy a kontrollert hívja:
router.get('/', employees.getEmployees)
Teljes kód:
module.exports = app => { const router = require('express').Router() const employees = require('../app/controllers/employee.controller') router.get('/', employees.getEmployees) app.use('/api/employees', router) }
A kontroller:
const { sequelize, Sequelize } = require('../models') const db = require('../models') db.employees = require('../models/employee')(sequelize, Sequelize) const Employee = db.employees exports.getEmployees = (req, res) => { Employee.findAll() .then(data => { res.send(data); }) .catch(err => { res.status(500).send({ message: err.message || "Hiba! Az adatbázis lekérése sikertelen" }) }) }
Vegyünk fel egy új routing bejegyzést:
router.post('/', employees.create)
Teljes kód:
module.exports = app => { const router = require('express').Router() const employees = require('../app/controllers/employee.controller') router.get('/', employees.getEmployees) router.post('/', employees.create) app.use('/api/employees', router) }
Most bővítsük a kontrollert:
//... exports.create = (req, res) => { if(!req.body.name) { res.status(400).send({ message: "A név megadása kötelező" }) return } const employee = { name: req.body.name, city: req.body.city, salary: req.body.salary } Employee.create(employee) .then( result => { res.send(result) }) }
Teljeskód:
const { sequelize, Sequelize } = require('../models') const db = require('../models') db.employees = require('../models/employee')(sequelize, Sequelize) const Employee = db.employees exports.getEmployees = (req, res) => { Employee.findAll() .then(data => { res.send(data); }) .catch(err => { res.status(500).send({ message: err.message || "Hiba! Az adatbázis lekérése sikertelen" }) }) } exports.create = (req, res) => { if(!req.body.name) { res.status(400).send({ message: "A név megadása kötelező" }) return } const employee = { name: req.body.name, city: req.body.city, salary: req.body.salary } Employee.create(employee) .then( result => { res.send(result) }) }
exports.update = (req, res) => { const { id } = req.params; if(!req.body.name) { res.status(400).send({ message: "A név megadása kötelező" }) return } const employee = { name: req.body.name, city: req.body.city, salary: req.body.salary }; Employee.update(employee,{ where: { id: id } }) .then((result) => { res.status(200).send({ msg: 'A frissítés sikeres', employee: employee }); }) .catch(err => { res.status(500).sendStatus({ message: err.message || "Hiba! Az adatbázis frissítése sikertelen" }); }); };
exports.destroy = (req, res) => { const { id } = req.params; Employee.destroy({ where: { id: id } }) .then(result => { res.status(200).send({Deleted: result}).json() }) .catch(err => { res.status(500).send({error: 'Hiba! A törlés sikertlen!'}).json(); }); }