Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

maggie-api

NaginB343ISC1.1.3TypeScript support: included

πŸ§™β€β™€οΈ A magical Express middleware to auto-generate CRUD APIs for Mongoose models with validation, unique keys, and middlewares.

express, mongoose, crud, api, typescript, joi, middleware, rest, auto-crud, maggie-api, nodejs, backend, typescript-library, typescript-express, express-crud, mongoose-crud, auto-rest-api, dynamic-api, api-generator, openapi, swagger, model-driven-api, validation, request-validation, api-validation, joi-validation, auto-validation, restful, json-api, controller-generator, schema-validation, typescript-backend, express-router, ts-api, developer-tools, boilerplate, api-boilerplate, crud-generator, api-scaffolding, rapid-development, productivity, modular-api, clean-architecture, mvc, mongoose-schema, typescript-utils, microservice, express-middleware, api-automation, ts-mongoose, dynamic-routing, express-tools, rest-framework, fast-api-setup, backend-generator

readme

πŸ§™β€β™€οΈ maggie-api

Auto-generate full-featured CRUD APIs for your Mongoose models in Express with one powerful config.

Supports:

  • βœ… Joi Validation
  • βœ… Custom Middlewares
  • βœ… Unique Primary Key Constraints
  • βœ… Add/Update Merged API
  • βœ… Consistent JSON Responses
  • βœ… Field Selection & Population
  • βœ… Bulk Insert Support
  • βœ… Dynamic Search (with keyword, fields, and case sensitivity support)
  • βœ… Pagination Support (limit & page query)
  • βœ… Sorting Support (ascending, descending, multi-field)
  • βœ… Filtering Support (with allowed fields and advanced operators like $gte, $in)
  • βœ… Auto Pluralized Response Keys
  • βœ… Full CRUD API Auto-generation

πŸ“¦ Installation

npm install maggie-api

# Peer dependencies
npm install express mongoose joi

πŸš€ Quick Start

import express from "express";
import { createMaggie } from "maggie-api";
import Models from "./models";
import Joi from "joi";

const app = express();
app.use(express.json());

const UserValidationSchema = Joi.object({
  _id: Joi.string(),
  firstName: Joi.string().required(),
  lastName: Joi.string().required(),
  email: Joi.string().email().required(),
});

const apiRouter = createMaggie({
  prefix: "/api/v1",
  models: [
    {
      model: ProductModel,
      path: "product",
      validationSchema: productValidationSchema,
      settings: {
        get: {
          // βœ… Only these fields will be returned in GET /product
          keys: ["_id", "title", "price", "description", "subCategory"],

          // πŸ” Search by title or description using `?search=some+word`
          search: {
            disabled: false,
            allowedFields: ["title", "description"],
          },

          // 🧹 Allow filtering via `?filter[price][gte]=100` or `filter[title]=Shoes`
          filter: {
            allowedFields: ["price", "title", "subCategory"],
          },

          // πŸ”— Populate referenced subCategory and its category
          populate: [
            {
              path: "subCategory",
              select: ["_id", "title"],
              populate: [{ path: "category", select: ["_id", "title"] }],
            },
          ],
        },

        getById: {
          // βœ… Only these fields will be returned in GET /product/:id
          keys: ["_id", "title", "description", "price", "subCategory"],

          // πŸ”— Nested populate same as `get`
          populate: [
            {
              path: "subCategory",
              select: ["_id", "title"],
              populate: [{ path: "category", select: ["_id", "title"] }],
            },
          ],
        },
      },
    },
  ],
});

app.use(apiRouter);

app.listen(3000, () => {
  console.log("Server running at http://localhost:3000");
});

πŸ›  Features

1. Add or Update API (POST /:model)

  • Merges create and update logic into a single endpoint.
  • If the request body contains _id, it triggers an update; otherwise, a new record is created.
  • Automatically checks primaryKey uniqueness during creation.
  • During update, it ignores the current document when checking for duplicates.

2. Joi Validation

  • Supports request body validation using Joi schemas for POST operations.
  • Only one validation error message is returned per request to enhance clarity.
  • Validation schemas are customizable per model.

3. Primary Key Uniqueness

  • Define a primaryKey (e.g. email, username) to enforce uniqueness on creation.
  • If a duplicate is found, the API returns a descriptive error.

4. Custom Middlewares

  • Use the middleWares array to inject custom Express middlewares into the POST route.
  • Enables features like authentication, authorization, logging, etc.

5. Field Filtering (Deprecated)

  • ⚠️ getKeys and getByIdKeys are deprecated.
  • Use settings.get.keys to select fields in GET /:model.
  • Use settings.getById.keys to select fields in GET /:model/:id.
  • This improves flexibility and aligns with modern structured configurations.

6. CRUD Endpoints (Auto-generated)

Method Endpoint Description
POST /api/v1/user Create or Update User
POST /api/v1/user/bulk Bulk Insert Users
GET /api/v1/user Fetch all Users
GET /api/v1/user/:id Fetch User by ID
DELETE /api/v1/user/:id Delete User by ID

7. Population Support

  • Use settings.get.populate and settings.getById.populate to populate referenced fields.
  • Each populate config accepts a path and optional select array for nested or targeted population.
settings: {
  get: {
    populate: [
      { path: "department", select: ["_id", "title"] }
    ]
  },
  getById: {
    populate: [
      {
        path: "department",
        select: ["_id", "title"] ,
        populate: [
          {
            path: "item",
            selected: ["_id", "title"]
          }
         ],
      }
    ]
  }
}

8. Search Support

  • βœ… Use settings.get.search to enable keyword-based searching on specific fields.
  • πŸ” Accepts query parameters like search, searchFields, and caseSensitive.
  • 🧩 Only fields defined in allowedFields will be considered for searching.
  • πŸ›‘ If disabled: true, searching will be turned off for that model.
  • 🌐 Falls back to all allowed fields if searchFields param is not provided.

Example Setting:

settings: {
  get: {
    search: {
      disabled: false,
      allowedFields: ["title", "description", "email"]
    }
  }
}

Sample Request:

GET /api/v1/user?search=mascara&searchFields=title,description&caseSensitive=false

Behavior:

  • Builds a $or regex search query for all specified fields.
  • If no valid fields are provided or allowed β†’ search is skipped.

9. Sorting, Pagination & Filtering (Built-in)

Sorting, pagination, and filtering are first-class citizens in maggie-api, available out of the box for all models.

#

πŸ”€ Sorting

  • Pass a sort query param to define sort order:

    ?sort=-createdAt,name
  • Use a hyphen (-) prefix for descending order.

  • Multiple fields can be sorted in sequence.
  • Sorting is always enabled β€” no extra config needed.

#

πŸ“„ Pagination

  • Supports standard pagination via limit and page query parameters:

    ?limit=10&page=2
  • Only applied when both parameters are valid positive integers.

  • Automatically returns metadata:

    {
      "users": [...],
      "pagination": {
        "total": 100,
        "page": 2,
        "limit": 10,
        "totalPages": 10
      }
    }
  • If not provided, returns the full result set without pagination.

πŸ“Œ Example:

GET /api/v1/product?filter[price][gte]=500&sort=-createdAt&limit=10&page=1

⚠️ Sorting and pagination are always enabled by default. Filtering requires configuring allowedFields to avoid accidental or insecure filtering.

This makes it easy to power powerful, customizable tables and dashboards with minimal backend configuration.


10. Filter Support

maggie-api allows powerful and flexible filtering on API endpoints using structured query parameters.

πŸ”§ Key Features:

  • Declarative control over filterable fields via settings.get.filter.allowedFields
  • Automatically transforms nested filters into MongoDB-compatible queries
  • Supports value types: primitives, arrays, and range operators

πŸ”€ Supported Operators:

Operator Usage Translates To
eq filter[status]=active { status: "active" }
in filter[tags][]=a&[]=b { tags: { $in: [...] } }
gte filter[price][gte]=100 { price: { $gte: 100 } }
lte filter[price][lte]=500 { price: { $lte: 500 } }
gt, lt Similar usage $gt, $lt

πŸ’‘ Behavior:

  • If a filter field is not included in allowedFields, it will be silently ignored.
  • Case-sensitive by default (you may use search for regex-based keyword lookups).
  • Compatible with MongoDB query syntax for advanced filtering.

πŸ§ͺ Example Request:

GET /api/v1/user?filter[role]=admin&filter[age][gte]=18

⚠️ Important:

  • Always whitelist filterable fields to avoid misuse or performance hits
  • For flexible keyword matching across multiple fields, use the search config instead

This filtering system is perfect for admin dashboards, search filters, and dynamic list views.


πŸ“‘ Sample cURL Commands

βž• Add a User

curl -X POST http://localhost:3000/api/v1/user \
-H "Content-Type: application/json" \
-d '{"firstName":"Alice","lastName":"Doe","email":"alice@example.com"}'

✏️ Update a User

curl -X POST http://localhost:3000/api/v1/user \
-H "Content-Type: application/json" \
-d '{"_id":"665c8d1234567890","firstName":"Alicia","email":"alice@example.com"}'

πŸ“„ Get All Users

curl http://localhost:3000/api/v1/user

πŸ” Get User by ID

curl http://localhost:3000/api/v1/user/665c8d1234567890

❌ Delete User by ID

curl -X DELETE http://localhost:3000/api/v1/user/665c8d1234567890

🚚 Bulk Insert Users

curl -X POST http://localhost:3000/api/v1/user/bulk \
-H "Content-Type: application/json" \
-d '[
  {"firstName":"Bob","lastName":"Smith","email":"bob@example.com"},
  {"firstName":"Carol","lastName":"Jones","email":"carol@example.com"}
]'

βœ… Standard JSON Response Format

maggie-api follows a consistent, frontend-friendly response structure for all CRUD operations.

🟒 On Success

Create:

{
  "success": true,
  "statusCode": 201,
  "message": "User created successfully",
  "data": {
    "_id": "665c8d1234567890",
    "firstName": "Alice",
    "email": "alice@example.com"
  }
}

Update:

{
  "success": true,
  "statusCode": 200,
  "message": "User updated successfully",
  "data": {
    "_id": "665c8d1234567890",
    "firstName": "Alicia"
  }
}

Get All (with optional pagination):

{
  "success": true,
  "statusCode": 200,
  "message": "Users fetched successfully",
  "data": {
    "users": [...],
    "pagination": {
      "total": 100,
      "page": 2,
      "limit": 10,
      "totalPages": 10
    }
  }
}

Get by ID:

{
  "success": true,
  "statusCode": 200,
  "message": "User fetched successfully",
  "data": {
    "_id": "665c8d1234567890",
    "firstName": "Alice"
  }
}

Delete:

{
  "success": true,
  "statusCode": 200,
  "message": "User deleted successfully",
  "data": {
    "_id": "665c8d1234567890"
  }
}

Bulk Insert:

{
  "success": true,
  "statusCode": 201,
  "message": "3 Users created successfully",
  "data": [{}, {}, {}]
}

πŸ”΄ On Errors

Validation Error:

{
  "success": false,
  "statusCode": 400,
  "message": "Validation error",
  "error": "\"email\" is required"
}

Duplicate Primary Key (Create or Bulk Insert):

{
  "success": false,
  "statusCode": 409,
  "message": "User with this email already exists",
  "data": null
}

Document Not Found (Update or GetById):

{
  "success": false,
  "statusCode": 404,
  "message": "User not found",
  "data": null
}

Invalid Request Format (e.g. Bulk Insert with non-array):

{
  "success": false,
  "statusCode": 400,
  "message": "Request body must be a non-empty array of documents",
  "data": null
}

Server Error:

{
  "success": false,
  "statusCode": 500,
  "message": "Failed to process User",
  "data": null
}

πŸ“‚ Example Project Structure

your-app/
β”œβ”€β”€ models/
β”‚   └── User.ts
β”œβ”€β”€ routes/
β”‚   └── index.ts
β”œβ”€β”€ utils/
β”‚   └── validateBody.ts
β”œβ”€β”€ app.ts
└── ...

πŸ‘ Contributing

Want to contribute or enhance? PRs are welcome!

  • Add new features like PATCH support, role-based auth, etc.
  • Improve test coverage
  • Bug fixes

πŸ“’ Final Words

Save hours of boilerplate setup. Focus on your app logic.

Let maggie-api handle the API plumbing. πŸš€