Features
- Advanced Filtering: Support for
gte
,gt
,lte
,lt
,in
,nin
,eq
,ne
,regex
operators. - Full-Text Search: Easily integrate search functionality across specified fields.
- Sorting: Order results by one or more fields, ascending or descending.
- Field Limiting: Select specific fields to return, reducing payload size.
- Pagination: Efficiently handle large datasets with page and limit parameters.
- Population: Seamlessly populate related Mongoose documents.
- TypeScript Support: Built with TypeScript for a better developer experience.
- Minimal Dependencies: Lightweight and focused on core functionality.
Installation
You can install the package using npm:
npm install mongoose-api-helpers
## Usage
### Basic Usage
Import the necessary functions and integrate them into your Mongoose queries.
```javascript
// For CommonJS
const { ApiFeatures, getPagination } = require("mongoose-api-helpers");
// For ES6 Modules / TypeScript
import { ApiFeatures, getPagination } from "mongoose-api-helpers";
// In your controller (example using Express.js)
// Assuming 'Product' is a Mongoose Model and 'req.query' contains your API query parameters.
export const getProducts = async (req, res) => {
try {
const features = new ApiFeatures(Product.find(), req.query)
.filter()
.search() // Searches default fields if not specified, or all string fields
.sort()
.limitFields()
.paginate()
.populate(); // Populates all specified in model schema virtuals by default
const results = await features.query;
const total = features.total || (await Product.countDocuments()); // Fallback to countDocuments if total is not set by paginate
const limit = parseInt(req.query.limit) || 10;
const page = parseInt(req.query.page) || 1;
res.status(200).json({
success: true,
count: results.length,
pagination: getPagination(total, limit, page),
data: results,
});
} catch (error) {
console.error(error); // Log the error for debugging
res.status(500).json({
success: false,
message: "Server Error",
error: error.message, // Provide error message for client
});
}
};
Advanced Usage with Customization
Customize search fields and populate options for fine-grained control.
import { ApiFeatures, getPagination } from "mongoose-api-helpers";
import { Request, Response } from "express";
import Product from "../models/Product"; // Your Mongoose Product Model
export const getProductsAdvanced = async (req: Request, res: Response) => {
try {
const features = new ApiFeatures(Product.find(), req.query)
.filter()
.search(["name", "description", "brand"]) // Custom search fields
.sort()
.limitFields()
.paginate()
.populate(["category", "reviews"]); // Custom populate options
const products = await features.query;
const total = features.total || (await Product.countDocuments());
const limit = parseInt(req.query.limit as string) || 10;
const page = parseInt(req.query.page as string) || 1;
res.status(200).json({
success: true,
count: products.length,
pagination: getPagination(total, limit, page),
data: products,
});
} catch (error: any) {
// Type 'any' for error for simpler example, consider specific error types
console.error(error);
res.status(500).json({
success: false,
message: "Server Error",
error: error.message,
});
}
};
API Response with Pagination
The getPagination
function helps format the pagination metadata for your API responses.
{
"success": true,
"count": 10,
"pagination": {
"total": 100,
"pages": 10,
"currentPage": 1,
"limit": 10,
"hasNext": true,
"hasPrevious": false,
"nextPage": 2,
"previousPage": null
},
"data": [
// Array of product objects
]
}
API Reference
ApiFeatures
Class
constructor(query: mongoose.Query, queryString: object)
query
: A Mongoose query object (e.g.,Model.find()
).queryString
: The request query parameters object (e.g.,req.query
from Express).
Methods
All methods are chainable and modify the internal query
object.
filter(): this
Applies advanced filtering based on query parameters. Supports operators like[gte]
,[gt]
,[lte]
,[lt]
,[in]
,[nin]
,[eq]
,[ne]
,[regex]
.search(searchFields?: string[]): this
Implements search functionality.searchFields
(optional): An array of strings specifying which fields to search within. If not provided, it attempts to search across all string fields in the model.
sort(): this
Handles sorting of results based on thesort
query parameter.limitFields(): this
Limits the fields returned in the query results based on thefields
query parameter.paginate(): this
Implements pagination based onpage
andlimit
query parameters. Setsthis.total
for convenience.populate(populateOptions?: string | string[] | mongoose.PopulateOptions | mongoose.PopulateOptions[]): this
Handles population of related Mongoose documents.populateOptions
(optional): Can be a string (field name), an array of strings, or MongoosePopulateOptions
object(s).
Properties
query: mongoose.Query
The modified Mongoose query object after all chained methods have been applied.total?: number
The total number of documents found before pagination, ifpaginate()
was called.
getPagination(total: number, limit: number, page: number): object
A helper function to generate pagination metadata for your API responses.
total
: The total number of documents available.limit
: The maximum number of results per page.page
: The current page number.
Returns an object with total
, pages
, currentPage
, limit
, hasNext
, hasPrevious
, nextPage
, and previousPage
properties.
Query Parameters
The package understands and processes the following query parameters:
page
: The desired page number (e.g.,page=2
).limit
: The number of results per page (e.g.,limit=10
).sort
: Fields to sort by, comma-separated. Prefix with-
for descending order (e.g.,sort=-price,createdAt
).fields
: Fields to return, comma-separated (e.g.,fields=name,price,category
).search
: The search term to apply (e.g.,search=apple
).populate
: Fields to populate, comma-separated (e.g.,populate=category,reviews
).- Filter operators: For any field, you can use
[gte]
,[gt]
,[lte]
,[lt]
,[in]
,[nin]
,[eq]
,[ne]
,[regex]
.
Examples
Filtering
Fetch products with a price between 100 and 500, and belonging to the 'electronics' category.
GET /api/products?price[gte]=100&price[lte]=500&category=electronics
Searching
Search for products containing the term 'apple' in their searchable fields.
GET /api/products?search=apple
Sorting
Sort products by price (descending) and then by creation date (ascending).
GET /api/products?sort=-price,createdAt
Field Selection
Return only the name
, price
, and category
fields for each product.
GET /api/products?fields=name,price,category
Pagination
Get the second page of results, with 10 items per page.
GET /api/products?page=2&limit=10
Population
Populate the category
and reviews
fields of each product.
GET /api/products?populate=category,reviews
TypeScript Support
This package is written in TypeScript and provides full type definitions out-of-the-box, ensuring a great development experience with type checking and autocompletion.
Contribution
Contributions are welcome! If you find a bug or have a feature request, please open an issue. If you'd like to contribute code, please follow these guidelines:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Ensure your code adheres to the existing style.
- Write tests for your changes.
- Follow the Git Commit Messages convention.
- Submit a pull request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Here's an image that symbolizes a well-documented and robust API feature package, perfect for a README file. It includes elements like code, a magnifying glass for searching/filtering, and pagination symbols.