REST API package for Express.js. Get full CRUD with filtering, sorting, pagination, validation, and hooks β in minutes.
Documentation: https://express-rest-api.rajesh-kumawat.in
- Zero boilerplate CRUD β Define a controller, get 6 REST endpoints
- Filtering, sorting, pagination β Built-in query parameter parsing
- Default adapter β Configure once, use in every controller
- Multi-ORM support β Prisma, Sequelize, Mongoose, Knex, Drizzle
- Lifecycle hooks β beforeStore, afterStore, beforeUpdate, etc.
- Validation β Zod, Joi, or custom functions (auto-detected)
- Hidden fields β Automatically strip sensitive data from responses
npm install @rkumwt/express-rest-apiInstall your ORM of choice:
npm install @prisma/client # Prisma
npm install sequelize # Sequelize
npm install mongoose # Mongoose
npm install knex # Knex
npm install drizzle-orm # DrizzleThis guide uses Prisma + SQLite. The steps are the same for any ORM β only the adapter changes.
npm install express @prisma/client
npm install -D prismaCreate prisma/schema.prisma:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
role String @default("user")
createdAt DateTime @default(now())
}Push the schema to create your database:
npx prisma db push// config/database.js β Database connection (shared singleton)
const { PrismaClient } = require('@prisma/client');
const db = new PrismaClient();
module.exports = db;// config/api.js β Set the adapter factory once for all controllers
const { configure, createPrismaAdapter } = require('@rkumwt/express-rest-api');
configure({
adapter: createPrismaAdapter,
});// controllers/UserController.js
const { ApiController } = require('@rkumwt/express-rest-api');
const db = require('../config/database');
class UserController extends ApiController {
// Adapter is auto-created from the factory set in config/api.js
model = db.user;
// Fields returned by default when client doesn't specify ?fields=
defaultFields = ['id', 'name', 'email', 'role', 'createdAt'];
// Fields allowed in ?filters=
filterableFields = ['id', 'name', 'email', 'role'];
// Fields allowed in ?order=
sortableFields = ['id', 'name', 'email', 'createdAt'];
}
module.exports = UserController;// routes/api.js
const { createApiRouter } = require('@rkumwt/express-rest-api');
const UserController = require('../controllers/UserController');
const api = createApiRouter({ prefix: '/api', version: 'v1' });
// Registers: GET, POST /api/v1/users + GET, PUT, PATCH, DELETE /api/v1/users/:id
api.apiResource('users', UserController);
module.exports = api;// server.js
const express = require('express');
const { apiErrorHandler } = require('@rkumwt/express-rest-api');
require('./config/api'); // Load adapter + global settings
const api = require('./routes/api');
const app = express();
app.use(express.json());
app.use(api.getRouter());
app.use(apiErrorHandler); // Handles 404, validation, and other API errors
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});node server.js# Create a user
curl -X POST http://localhost:3000/api/v1/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
# List all users
curl http://localhost:3000/api/v1/users
# Get a single user
curl http://localhost:3000/api/v1/users/1
# Update a user
curl -X PUT http://localhost:3000/api/v1/users/1 \
-H "Content-Type: application/json" \
-d '{"name": "John Doe"}'
# Delete a user
curl -X DELETE http://localhost:3000/api/v1/users/1That's it! You have a full REST API with filtering, sorting, and pagination built in.
# Select specific fields
GET /api/v1/users?fields=id,name,email
# Include relations
GET /api/v1/users?fields=id,name,posts{id,title}
# Filter
GET /api/v1/users?filters=(role eq admin)
GET /api/v1/users?filters=(role eq admin and status eq active)
GET /api/v1/users?filters=(name lk john)
# Sort
GET /api/v1/users?order=name asc
GET /api/v1/users?order=name asc, id desc
# Paginate
GET /api/v1/users?limit=10&offset=20Filter operators: eq ne gt ge lt le lk
// GET /api/v1/users
{
"data": [
{ "id": 1, "name": "John", "email": "john@example.com" }
],
"meta": {
"paging": {
"total": 87,
"limit": 10,
"offset": 0,
"previous": null,
"next": "/api/v1/users?limit=10&offset=10"
},
"timing": "5ms"
}
}
// GET /api/v1/users/1
{ "data": { "id": 1, "name": "John", "email": "john@example.com" } }
// POST /api/v1/users β 201
{ "data": { "id": 42, "name": "John" }, "message": "Resource created successfully" }
// DELETE /api/v1/users/1 β 200
{ "message": "Resource deleted successfully" }Change one line in config β all controllers stay the same:
// Prisma
configure({ adapter: createPrismaAdapter });
// Sequelize
configure({ adapter: createSequelizeAdapter });
// Mongoose
configure({ adapter: createMongooseAdapter });You can also set the adapter explicitly per controller (overrides config):
class UserController extends ApiController {
adapter = createPrismaAdapter(db.user); // Explicit β overrides config
}Full documentation with examples, hooks, validation, and API reference:
https://express-rest-api.rajesh-kumawat.in
If you find this package useful, please consider supporting it:
- Star this repo β It helps others discover the project
- Fork it β Contribute features, fixes, or improvements
- Share it β Tell other developers about it
MIT