NODERYX
FRAMEWORK v0.7.1

GETTING STARTED

BUILDING

PRODUCTION

DEVICES

REFERENCE

NODERYX / DOCS / BUILDING / 03
BUILDING / 03

Database & models

One model API across MySQL, PostgreSQL, and MongoDB—with migrations, seeders, and lifecycle observers.

01

Choose a driver

DB_TYPE selects the connection shape in noderyx.config.js. Drivers are optional dependencies, so an application that does not use a database installs nothing extra.

.env
DB_TYPE=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_USER=root DB_PASSWORD= DB_NAME=my_app # or DB_TYPE=postgres DATABASE_URL=postgresql://user:password@localhost:5432/my_app # or DB_TYPE=mongo MONGODB_URL=mongodb://localhost:27017 DB_NAME=my_app
02

Connect once, share everywhere

connect() returns an adapter for the configured driver. Register it as a service and hand it to the models that need it—do not open a connection per request.

server.js
import { connect } from "noderyx-framework"; import { User } from "./app/Models/User.js"; const db = await connect(config.database); app.provide("db", db); User.use(db);
NOTE

The adapter exposes db.kind, so code that must branch per engine can do so explicitly.

03

Define a model

A model names its table, its primary key, and the fields that may be written. Anything outside fillable is dropped before it reaches the database.

app/Models/User.js
import { Model } from "noderyx-framework"; export class User extends Model { static table = "users"; static fillable = ["name", "email"]; }
NOTE

Generate it with npx noderyx make:model User --table=users.

04

Read and write records

The same five methods work on every supported engine, so moving from MongoDB to PostgreSQL does not rewrite your application code.

JAVASCRIPT
const users = await User.all(); const user = await User.find(1); const created = await User.create({ name: "Ada", email: "ada@example.com" }); await User.update(created.id, { name: "Ada Lovelace" }); await User.delete(created.id);
NOTE

Queries are parameterised, and table and column names are validated, so untrusted input cannot become SQL.

05

Write a migration

Migrations are timestamped modules exporting up(db) and down(db). The generated file branches on db.kind, which is how one migration serves both SQL engines and MongoDB.

database/migrations/20260714090000_create_users.js
export async function up(db) { if (db.kind === "mongo") { await db.createCollection("users").catch(() => {}); return; } await db.query(` CREATE TABLE users ( id INTEGER PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) `); }
NOTE

Always write down(db) as well—rollback is only as good as the reverse you provided.

06

Run and inspect migrations

Applied migrations are recorded, so running migrate repeatedly is safe. Check the state before deploying, and roll back in batches when something is wrong.

TERMINAL
npm run migrate npx noderyx migrate:status npx noderyx migrate:rollback --steps=1
07

Seeders

A seeder exports async run(db) and receives the same adapter models use. Seeders are for reference data and realistic development fixtures.

database/seeders/RoleSeeder.js
export async function run(db) { await db.query("INSERT INTO roles (name) VALUES (?)", ["admin"]); }
NOTE

Run everything with npm run seed, or one file with npx noderyx db:seed --class=RoleSeeder.

08

Observers

An observer reacts to a model's lifecycle without cluttering controllers—hash a password before create, invalidate a cache after update, archive a record before delete.

app/Observers/UserObserver.js
export class UserObserver { async creating(values) {} async created(model) {} async updating(payload) {} async updated(model) {} async deleting(id) {} async deleted(id) {} } User.observe(new UserObserver());
09

Passwords belong in the database hashed

The framework hashes with scrypt and compares in constant time, so a wrong password takes as long to reject as a right one.

JAVASCRIPT
import { hashPassword, verifyPassword } from "noderyx-framework"; const stored = await hashPassword(plainText); const ok = await verifyPassword(attempt, stored);
NOTE

Generate a hash for a first administrator from the terminal: npx noderyx hash "a long passphrase".

10

Practical safeguards

A few habits keep data work predictable across environments.

  • Keep credentials in .env, never in noderyx.config.js or a committed file.
  • Treat migrations as append-only: fix a mistake with a new migration, not by editing history.
  • Give each environment its own database; seed development and test freely.
  • Run migrate:status as part of deployment so drift is visible before traffic arrives.
  • Keep the fillable list narrow—it is the difference between an update and a privilege escalation.