@ferjssilva/fast-crud-api
Version:
A complete and fast crud API generator
267 lines (209 loc) ⢠5.84 kB
Markdown
# Fast CRUD API
A lightweight and flexible REST API generator for Fastify and MongoDB. Create fully-featured CRUD APIs with minimal configuration.
## Quick Install
```bash
npm install @ferjssilva/fast-crud-api
```
### Dependencies
- fastify (peer dependency)
- mongoose (peer dependency)
- fastify-plugin
## Features
- š Full CRUD operations out of the box
- š Automatic pagination
- š Text search across string fields
- š Reference population support
- š± Nested routes for relationships
- šÆ Method restrictions per model
- ļæ½ User-scoped resources with automatic filtering
- ļæ½š Query building with filtering and sorting
- ā” MongoDB integration with proper document transformation
- š Clean REST API endpoints
- šØ Comprehensive error handling
- ā
100% Test Coverage
## How to Use
### Basic Setup
```javascript
const fastify = require('fastify')()
const mongoose = require('mongoose')
const fastCrudApi = require('@ferjssilva/fast-crud-api')
// Your mongoose models
const User = require('./models/User')
const Post = require('./models/Post')
// Register the plugin
fastify.register(fastCrudApi, {
prefix: '/api',
models: [User, Post],
methods: {
// Optional: restrict methods per model
users: ['GET', 'POST', 'PUT', 'DELETE'],
posts: ['GET', 'POST']
},
userScoped: ['posts'] // Optional: automatically filter resources by userId
})
```
### API Usage
#### List Resources
```http
GET /api/users?page=1&limit=10
GET /api/users?sort={"createdAt":-1}
GET /api/users?name=John&age=25
GET /api/users?search=john
```
#### Get Single Resource
```http
GET /api/users/:id
GET /api/users/:id?populate=posts
```
#### Create Resource
```http
POST /api/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
```
#### Update Resource
```http
PUT /api/users/:id
Content-Type: application/json
{
"name": "John Updated"
}
```
#### Delete Resource
```http
DELETE /api/users/:id
```
#### Nested Routes
```http
GET /api/users/:userId/posts
```
### User-Scoped Resources
Automatically filter and secure resources by user ID. Perfect for multi-tenant applications where users should only access their own data.
```javascript
fastify.register(fastCrudApi, {
prefix: '/api',
models: [User, Post, UserHabit],
userScoped: ['user-habits'] // Resources that require user isolation
})
```
**How it works:**
1. **Authentication Required**: User-scoped resources require `request.userId` to be set (typically by an authentication middleware)
2. **Automatic Filtering**:
- GET requests automatically filter by `userId`
- POST requests automatically inject `userId` into new documents
- PUT/DELETE requests verify ownership atomically
3. **Security**:
- Users cannot access other users' data
- Users cannot modify `userId` on their resources
- Ownership checks prevent TOCTOU vulnerabilities
**Example with Authentication:**
```javascript
// Authentication middleware to set request.userId
fastify.addHook('preHandler', async (request, reply) => {
const token = request.headers.authorization?.split(' ')[1];
const user = await verifyToken(token);
if (user) {
request.userId = user.id; // Set userId for user-scoped resources
}
});
// User-scoped resources
fastify.register(fastCrudApi, {
prefix: '/api',
models: [UserHabit, UserProfile],
userScoped: ['user-habits', 'user-profiles']
});
```
**Usage:**
```http
# List user's own habits (automatically filtered)
GET /api/user-habits
Authorization: Bearer <token>
# Create habit (userId injected automatically)
POST /api/user-habits
Authorization: Bearer <token>
Content-Type: application/json
{
"habitId": "exercise-daily",
"frequency": "daily"
}
# Update only if user owns the resource
PUT /api/user-habits/:id
Authorization: Bearer <token>
# Delete only if user owns the resource
DELETE /api/user-habits/:id
Authorization: Bearer <token>
```
### Response Format
#### List Response
```javascript
{
"data": [...],
"pagination": {
"total": 100,
"page": 1,
"limit": 10,
"pages": 10
}
}
```
#### Single Resource Response
```javascript
{
"id": "...",
"field1": "value1",
"field2": "value2"
}
```
#### Error Response
```javascript
{
"error": "ErrorType",
"message": "Error description",
"details": [] // Optional validation details
}
```
## Project Structure
The library is organized in a modular structure for better maintainability:
```
src/
āāā index.js # Main plugin module
āāā utils/
ā āāā document.js # Document transformation utilities
ā āāā query.js # Query building utilities
āāā middleware/
ā āāā error-handler.js # Error handling middleware
ā āāā user-scope.js # User-scoped resource middleware
āāā routes/
ā āāā crud.js # CRUD route handlers
ā āāā nested.js # Nested route handlers
āāā validators/
āāā method.js # Method validation utilities
```
## Issues and Contact
If you encounter any issues or have suggestions for improvements, please open an issue on our GitHub repository. We appreciate your feedback and contributions!
[Open an Issue](https://github.com/ferjssilva/fast-crud-api/issues)
## Testing
The library includes comprehensive unit tests to ensure the correct functioning of all components:
```bash
# Run all tests
npm test
# Run tests with coverage report
npm run test:coverage
# Run tests in watch mode (useful during development)
npm run test:watch
```
Code coverage results:
- Lines of code: 100%
- Functions: 100%
- Branches: 100%
- Statements: 100%
We've achieved complete coverage for all components:
- Utils: 100%
- Validators: 100%
- Middleware: 100%
- Routes: 100%
## License
ISC License