Skip to content
flutterbuddy1Public

About

A production-ready, database-agnostic REST API builder for Node.js with built-in validation, multi-database support, and extensive customization options.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

DBCrud

A production-ready, database-agnostic REST API builder for Node.js with built-in validation, multi-database support, and extensive customization options.

Features

  • 🚀 Zero Configuration: Auto-generates REST API routes from your models
  • 🔒 Built-in Validation: Automatic validation using Joi with customizable schemas
  • 🗄️ Multi-Database Support: Works with MongoDB (Mongoose), PostgreSQL, MySQL, SQLite (Sequelize, Prisma), and custom adapters
  • 🎯 Production Ready: Comprehensive error handling, validation, and security best practices
  • 🔧 Highly Customizable: Middleware support, custom validation, route selection, and more
  • 📦 Lightweight: Minimal dependencies, only install what you need
  • 📘 TypeScript Support: Full TypeScript type definitions included

Installation

npm install dbcrud

For MongoDB support:

npm install mongoose

For SQL databases with Sequelize (PostgreSQL, MySQL, SQLite):

npm install sequelize
# And the appropriate driver:
npm install pg pg-hstore        # PostgreSQL
npm install mysql2               # MySQL
npm install sqlite3              # SQLite

For Prisma (PostgreSQL, MySQL, SQLite, SQL Server, MongoDB):

npm install @prisma/client
npm install -D prisma
npx prisma init
# Configure your schema.prisma and run:
npx prisma generate

Quick Start

MongoDB Example

const express = require('express');
const mongoose = require('mongoose');
const { buildRouter, errorHandler } = require('dbcrud');

// Define your Mongoose model
const UserSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    role: { type: String, default: 'user' }
});
const User = mongoose.model('User', UserSchema);

// Connect to database
await mongoose.connect('mongodb://localhost:27017/mydb');

// Create Express app
const app = express();
app.use(express.json());

// Build REST API router (auto-generates all CRUD routes)
const userRouter = buildRouter(User);
app.use('/api/users', userRouter);

// Add error handler
app.use(errorHandler);

app.listen(3000);

That's it! You now have a fully functional REST API with:

  • GET /api/users - List users (with pagination, filtering, sorting)
  • GET /api/users/:id - Get user by ID
  • POST /api/users - Create user (with validation)
  • PUT /api/users/:id - Update user
  • DELETE /api/users/:id - Delete user

Sequelize Example

const { Sequelize, DataTypes } = require('sequelize');
const { buildRouter, errorHandler } = require('dbcrud');

// Define Sequelize model
const sequelize = new Sequelize('sqlite::memory:');
const User = sequelize.define('User', {
    name: { type: DataTypes.STRING, allowNull: false },
    email: { type: DataTypes.STRING, allowNull: false, unique: true },
    role: { type: DataTypes.STRING, defaultValue: 'user' }
});

await User.sync();

// Use the same buildRouter - it auto-detects Sequelize models!
const app = express();
app.use(express.json());
app.use('/api/users', buildRouter(User));
app.use(errorHandler);
app.listen(3000);

Prisma Example

const express = require('express');
const { PrismaClient } = require('@prisma/client');
const { buildRouter, errorHandler, Joi } = require('dbcrud');

// Initialize Prisma Client
const prisma = new PrismaClient();

// Create Express app
const app = express();
app.use(express.json());

// Custom validation (optional)
const userCreateSchema = Joi.object({
    name: Joi.string().min(2).max(100).required(),
    email: Joi.string().email().required(),
    role: Joi.string().valid('user', 'admin').default('user')
});

// Build router with Prisma
// Pass prismaClient and modelName in options
const userRouter = buildRouter(null, {
    prismaClient: prisma,
    modelName: 'user', // lowercase, singular model name from your schema.prisma
    validation: {
        create: userCreateSchema
    }
});

app.use('/api/users', userRouter);
app.use(errorHandler);

// Graceful shutdown
process.on('beforeExit', async () => {
    await prisma.$disconnect();
});

app.listen(3000);

Note: For Prisma, you need to:

  1. Define your schema in schema.prisma
  2. Run npx prisma generate to generate the Prisma Client
  3. Pass prismaClient and modelName (lowercase, singular) in the options

API Reference

buildRouter(Model, options)

Creates an Express router with REST API routes for your model.

Parameters

  • Model (required for Mongoose/Sequelize, null for Prisma): Your database model
  • options (optional): Configuration object

Options

{
    // Route selection
    only: ['index', 'show', 'create', 'update', 'delete'], // Default: all routes
    
    // Pagination
    pageSize: 10, // Default page size
    
    // Validation
    validation: {
        create: JoiSchema,      // Custom schema for POST requests
        update: JoiSchema,      // Custom schema for PUT requests
        query: JoiSchema,       // Custom schema for query parameters
        params: JoiSchema,      // Custom schema for route parameters
        autoGenerate: true      // Auto-generate from model schema (default: true)
    },
    
    // Middleware
    middlewares: {
        index: [middleware1, middleware2],   // Middleware for GET /
        show: [middleware1],                 // Middleware for GET /:id
        create: [middleware1],                // Middleware for POST /
        update: [middleware1],               // Middleware for PUT /:id
        delete: [middleware1]                // Middleware for DELETE /:id
    },
    
    // Custom database adapter
    adapter: CustomAdapterClass,
    
    // Prisma-specific options (when using Prisma)
    prismaClient: PrismaClientInstance,  // PrismaClient instance
    modelName: 'user'                     // Model name (lowercase, singular)
}

Advanced Usage

Custom Validation

const { buildRouter, Joi } = require('dbcrud');

const userCreateSchema = Joi.object({
    name: Joi.string().min(2).max(100).required(),
    email: Joi.string().email().required(),
    role: Joi.string().valid('user', 'admin').default('user')
});

const userRouter = buildRouter(User, {
    validation: {
        create: userCreateSchema,
        update: userCreateSchema.keys().optional(),
        autoGenerate: false // Disable auto-generation
    }
});

Custom Middleware

const authMiddleware = (req, res, next) => {
    if (!req.headers.authorization) {
        return res.status(401).json({ error: 'Unauthorized' });
    }
    next();
};

const userRouter = buildRouter(User, {
    middlewares: {
        create: [authMiddleware],
        update: [authMiddleware],
        delete: [authMiddleware]
    }
});

Select Specific Routes

// Only enable read operations
const userRouter = buildRouter(User, {
    only: ['index', 'show']
});

Custom Database Adapter

const { BaseAdapter } = require('dbcrud');

class CustomAdapter extends BaseAdapter {
    async findAll(query, options) {
        // Your custom implementation
    }
    // ... implement other methods
}

const userRouter = buildRouter(MyModel, {
    adapter: CustomAdapter
});

Query Parameters

List Endpoint (GET /api/users)

  • page: Page number (default: 1)
  • limit: Items per page (default: 10)
  • sort: Sort field(s) - ?sort=name or ?sort=-createdAt (descending)
  • fields: Select specific fields - ?fields=name,email
  • Filtering: Any other query params are used as filters - ?role=admin&status=active

Examples

# Get first page
GET /api/users

# Get second page with 20 items
GET /api/users?page=2&limit=20

# Sort by name descending
GET /api/users?sort=-name

# Filter by role
GET /api/users?role=admin

# Combine filters
GET /api/users?role=admin&status=active&sort=-createdAt&page=1&limit=10

# Select specific fields
GET /api/users?fields=name,email

Response Format

Success Response

{
    "success": true,
    "data": [...],
    "meta": {
        "total": 100,
        "page": 1,
        "limit": 10,
        "totalPages": 10
    }
}

Error Response

{
    "success": false,
    "error": "Error message",
    "details": [...] // Optional validation details
}

Error Handling

The package includes comprehensive error handling:

  • 400 Bad Request: Validation errors
  • 404 Not Found: Resource not found
  • 409 Conflict: Duplicate key errors
  • 500 Internal Server Error: Server errors

Use the errorHandler middleware to handle all errors:

const { errorHandler } = require('dbcrud');
app.use(errorHandler);

Supported Databases

MongoDB (Mongoose)

✅ Fully supported with auto-detection

PostgreSQL (Sequelize)

✅ Fully supported with auto-detection

MySQL (Sequelize)

✅ Fully supported with auto-detection

SQLite (Sequelize)

✅ Fully supported with auto-detection

Prisma (PostgreSQL, MySQL, SQLite, SQL Server, MongoDB)

✅ Fully supported - Pass prismaClient and modelName in options

Custom Databases

✅ Create your own adapter by extending BaseAdapter

Production Considerations

  1. Environment Variables: Use environment variables for database connections
  2. Error Logging: The error handler logs errors in production
  3. Rate Limiting: Add rate limiting middleware for production
  4. CORS: Configure CORS appropriately
  5. Helmet: Use security middleware like Helmet
  6. Validation: Always use custom validation schemas in production
  7. Authentication: Implement proper authentication/authorization

Example production setup:

const helmet = require('helmet');
const rateLimit = require('express-rate-limit');

app.use(helmet());
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));

// Your routes...
app.use(errorHandler);

Examples

Check the example/ directory for complete examples:

  • server-simple.js - Minimal setup
  • server-mongoose.js - MongoDB with custom validation
  • server-sequelize.js - Sequelize with SQLite
  • server-prisma.js - Prisma with SQLite
  • server-typescript.ts - TypeScript example with full type safety
  • models/User.js - Mongoose model example
  • models/UserSequelize.js - Sequelize model example
  • schema.prisma - Prisma schema example

TypeScript Support

This package includes full TypeScript type definitions. Simply import and use with full type safety:

import { buildRouter, errorHandler, Joi, RouterOptions } from 'dbcrud';
import mongoose from 'mongoose';

const User = mongoose.model('User', userSchema);

const options: RouterOptions = {
    only: ['index', 'show', 'create'],
    validation: {
        create: Joi.object({
            name: Joi.string().required(),
            email: Joi.string().email().required()
        })
    }
};

const router = buildRouter(User, options);

All exports are fully typed, including:

  • buildRouter function and options
  • ApiError class
  • Validation middleware functions
  • Database adapters
  • Error handler middleware

License

ISC

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

A production-ready, database-agnostic REST API builder for Node.js with built-in validation, multi-database support, and extensive customization options.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages