@medyll/idae-api
v0.187.2
Published
A flexible and extensible API framework for Node.js, designed to work with multiple database types and configurations. It features a modular architecture, dynamic database connection management, and a flexible routing system. The framework supports TypeSc
Readme
@medyll/idae-api
A flexible and extensible Node.js API, based on the @medyll/idae-db library, allowing you to manage multiple types of databases (MongoDB, MySQL, etc.) and providing a complete TypeScript client to interact with your endpoints.
Table of Contents
- Overview
- Installation
- Main Features
- Server Usage
- Client Usage
- Full List of Methods (inherited from idae-db)
- Contributing
- License
Overview
@medyll/idae-api is a modular Node.js API framework designed to work with multiple database types thanks to the @medyll/idae-db library. It offers:
- Modular architecture (routes, middlewares, dynamic connection management)
- TypeScript/JavaScript client for easy API consumption
- Extension system to support other databases
- Native support for MongoDB and MySQL (via idae-db)
- Hooks/events on CRUD operations
- MongoDB-like API syntax: All query and update operations use a syntax very close to MongoDB (operators like
$in,$gt,$set, etc.), making it intuitive for developers familiar with MongoDB.
Installation
npm install @medyll/idae-api
npm install @medyll/idae-api --latest # to install the latest version
npm install @medyll/idae-api --next # for the next version (if available)
Main Features
- Multi-database management (MongoDB, MySQL, etc.)
- Flexible routing and custom route addition
- Optional authentication middleware
- Centralized error handling
- Hooks/events on all CRUD operations
- Complete TypeScript client for API consumption
- Inherits all advanced methods from @medyll/idae-db
- Comprehensive middleware system for authentication, authorization, validation, multi-tenancy, docs, and health endpoints
- Strict multi-tenancy: Tenant context required for all requests (see below)
- Robust error handling: All errors are handled by a centralized middleware
Advanced (2026):
- OpenAPI auto-generation & docs:
/openapi.json(spec),/docs(Swagger UI),/redoc(Redoc) - RBAC/ABAC: Per-route authorization via JWT roles/scopes (see
authorizationin route definitions) - Strict multi-tenancy: Tenant context required for all requests (from JWT, e.g.
tenantIdclaim) - Security/validation: CORS, helmet, rate limiting, payload limits, Zod validation, DB guardrails, health endpoints
Middleware, Multi-Tenancy, and Error Handling
This project uses a comprehensive middleware system for authentication, authorization, validation, multi-tenancy, documentation, and health endpoints. See src/lib/server/middleware/README.md for a full list and integration order.
Multi-tenancy is enforced via tenantContextMiddleware, which extracts the tenant context from the JWT or user object and injects it into the request. All protected routes require a valid tenant context. See the developer docs and middleware README for details and options.
Error handling is centralized: any error thrown in a route or middleware is caught and returned as a JSON error response with the appropriate status code.
Testing: Extensive tests cover edge cases, error handling, and multi-tenancy scenarios. See src/lib/server/__tests__/middleware/ for examples.
CI/CD: The test suite must pass for all changes. Run npm run test locally and ensure your CI pipeline is green before merging.
Server Usage
Configuration
import { idaeApi } from '@medyll/idae-api';
idaeApi.setOptions({
port: 3000,
enableAuth: true, // or false
jwtSecret: 'your-secret-key',
tokenExpiration: '1h',
routes: customRoutes // optional
});
idaeApi.start();Example of custom routes
const customRoutes = [
{
method: 'get',
path: '/custom/hello',
handler: async () => ({ message: 'Hello from custom route!' }),
requiresAuth: false
}
];
idaeApi.router.addRoutes(customRoutes);Database Management
idae-api relies on @medyll/idae-db for connection and database operation management. You can:
- Add new database adapters (see the
DatabaseAdapterinterface in idae-db) - Use all hooks/events from idae-db (see below)
Error Handling
An error handling middleware is included. You can customize it via the configureErrorHandling method in the IdaeApi class.
Client Usage
Client Configuration
import { IdaeApiClientConfig } from '@medyll/idae-api';
IdaeApiClientConfig.setOptions({
host: 'localhost',
port: 3000,
method: 'http',
defaultDb: 'idae_base',
separator: '//'
});Creating a client instance
import { IdaeApiClient } from '@medyll/idae-api';
const client = new IdaeApiClient();Available Methods
Database and Collection Management
getDbList(): List available databasesgetCollections(dbName): List collections in a databasedb(dbName): Select a database (returns an object withcollectionandgetCollections)collection(collectionName, dbName?): Select a collection (optionally in a given database)
Event/Hook Management (inherited from idae-db)
You can register hooks on all operations:
const usersCollection = client.collection('user');
usersCollection.registerEvents({
findById: {
pre: (id) => console.log(`Before searching for ID: ${id}`),
post: (result, id) => console.log(`Result for ${id}:`, result),
error: (error) => console.error('Error on findById:', error)
},
// ... same for update, create, etc.
});
#### CRUD Operations on a Collection
All the following methods are available via the `IdaeApiClientCollection` object:
- `findAll(params?)` : List all documents (with filters, sorting, pagination)
- `findById(id)` : Get a document by its ID
- `findOne(params)` : Get a document by a filter (inherited from idae-db)
- `create(body)` : Create a document
- `update(id, body)` : Update a document
- `deleteById(id)` : Delete a document by its ID
- `deleteManyByQuery(params)` : Delete multiple documents by filter
#Usage Examples
MongoDB-like Query Syntax
All query and update operations use a syntax very close to MongoDB. For example, you can use operators like $in, $gt, $set, etc. in your queries and updates.
List databases
const dbList = await client.getDbList();
console.log('Databases:', dbList);List collections in a database
const collections = await client.getCollections('idae_base');
console.log('Collections:', collections);Find documents with advanced query (MongoDB-like)
const userCollection = client.db('app').collection('user');
const users = await userCollection.find({
email: { $in: ["[email protected]", "Test@Value"] },
age: 31,
});
console.log(users);Create a new document
const newUser = await userCollection.create({
name: "new user",
email: "Test@Value",
});
console.log(newUser);Find all documents in a collection
const allDocs = await userCollection.findAll();
console.log(allDocs);Find a specific document by ID
const foundDoc = await userCollection.findById(newUser._id);
console.log(foundDoc);Update a document (MongoDB-like update syntax)
const updatedDoc = await userCollection.update(newUser._id, {
$set: { value: "Updated Value" },
});
console.log(updatedDoc);Delete a document
const deleteResult = await userCollection.deleteById(newUser._id);
console.log(deleteResult);Use a specific database and collection
const appSchemeCollection = client.db('idae_base').collection('appscheme');
const docs = await appSchemeCollection.findAll();
console.log(docs);Delete many documents by query (be careful with this!)
const deleteResult2 = await client
.collection('appscheme_base')
.deleteManyByQuery({ testField: 'testValue' });
console.log(deleteResult2);Register hooks/events on collection methods
const usersCollection = client.collection('user');
usersCollection.registerEvents({
findById: {
pre: (id) => console.log(`Before searching for ID: ${id}`),
post: (result, id) => console.log(`Result for ${id}:`, result),
error: (error) => console.error('Error on findById:', error)
},
// ... same for update, create, etc.
});Full List of Methods (inherited from idae-db)
Collection Methods
find(params): Advanced search (filters, sorting, pagination)findOne(params): Find a single document by filterfindById(id): Find by IDcreate(data): Createupdate(id, data): UpdatedeleteById(id): Delete by IDdeleteManyByQuery(params): Bulk deleteregisterEvents(events): Register hooks (pre/post/error) on each method
Connection Management
closeAllConnections(): Close all active connections
Useful Types
RequestParams:Record<string, unknown>HttpMethod:'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'RouteNamespace:methods/${'dbs' | 'collections'}UrlParams:{ dbName?: string; collectionName?: string; slug?: string; params?: Record<string, string>; routeNamespace?: RouteNamespace }RequestOptions<T>:UrlParams & { baseUrl?: string; method?: HttpMethod; body?: T; headers?: RequestInit['headers'] }
Contributing
Contributions are welcome! Feel free to submit a Pull Request.
Erreurs courantes & troubleshooting
Voici quelques problèmes fréquemment rencontrés et leurs solutions rapides :
- req.idaeDb ou req.connectedCollection undefined : la route ne correspond pas au pattern attendu ou le middleware n’est pas appliqué. Vérifie le chemin et l’ordre des middlewares.
- Token invalide sur route protégée : header Authorization absent/mal formé, ou token expiré. Vérifie la config côté client et serveur.
- Timeout ou erreur de connexion MongoDB : URI incorrect ou service MongoDB non démarré. Vérifie la chaîne de connexion et l’état du service.
- Résultat de requête vide : mauvais nom de collection/db, ou filtre trop restrictif. Loggue les paramètres pour debug.
- 404 ou handler non appelé : route non enregistrée ou méthode HTTP incorrecte. Vérifie la déclaration dans routeDefinitions.ts.
- Mismatch de types client/serveur : le serveur doit retourner des objets sérialisables, le client doit utiliser les bons types génériques.
- Middleware d’auth non appliqué partout : chaque route protégée doit avoir requiresAuth: true et l’auth doit être activée dans la config.
Pour plus de détails et de cas avancés, consulte :
Schéma d’architecture (à compléter)
flowchart TD
Client <--> API[IdaeApi (Express)]
API --> MW[Middleware]
MW --> DB[IdaeDbAdapter (MongoDB/MySQL)]
API --> Auth[Auth/JWT]
API --> Docs[OpenAPI/Swagger]
MW --> MultiTenancy[TenantContext]License
This project is licensed under the MIT License.
