drapi
v1.8.50
Published
Dynamic rest api using mongoDb
Downloads
103
Readme
Drapi
Dynamic Rest Api (DRAPI) is a koaJs middleware, used to provide a REST Api in which you can dynamically define the controllers and its model's structure in a mongoDB database.
It also provides support for dynamic database connections based on a configurable request header param.
Overview
- Dynamic database connections based on a header param (wp)
- Dynamic rest apis (controllers) based on table on database (model)
- Dynamic models definition based on table on database (structure)
Installation
$ npm install drapi --save
Usage
App Skelleton
- Clone the drapi skelleton app
- Delete the Git folder (.git)
- In the app.js file it imports drapi and loads dynamic rest routes and custom routes
const config = require('./config');
const Drapi = require('drapi');
const path = require('path');
const app = new Koa();
const drapi = new Drapi(config);
//load rest blueprints methods for custom rest controllers
app.use(drapi.customRest(path.join(__dirname,'/api/controllers')));
//load rest blueprints methods for dynamic rest controllers
app.use(drapi.dynamicRest());
- Run the app
$ npm run start
Configuration
The required configurations for drapi can be found in the /config/ folder.
You can set different configuration for each enviroment: development, testing, production.
The final json looks something like this:
{
"port": 3000,
"db": {
"defaultDbName": "basehcm",
"headerDbName": "wp",
"host": "mongodb://localhost/"
},
"env": "development",
"appBaseUrl": "/",
"hostName": "http://localhost:3000"
}
- port: port number in which the api will be exposed
- db.defaultDbName: Name of the default database to use when no header param recieved
- db.headerDbName: Name of the header attribute in which the database name will be specified
- db.host: Host of the mongoDB server
- env: Current enviroment
- appBaseUrl: Root path
- hostName: App hostname to use
Database configuration
Drapi uses mongoDB as its default database engine
Static Collections
- Model: collection in which all the desired controllers for the dynamic rest api should be inserted
{
"_id":{
"type":"string"
},
"name":{
"type":"string"
}
}
//Eg.
{
"_id":"country",
"name":"Country"
}
- Structure: collection in whick the structure of the model for the controller should be inserted
{
"_id":{
"type":"string"
},
"structure": {
"type":"Mixed"
}
}
//Eg.
{
"_id":"country",
"structure":{"_id":{"type":"ObjectId","primaryKey":true,"hidden":true,"auto":true},"name":{"type":"string","label":"Nombre"}}
}
####Dynamic Collections
Every document in the "model" collection will become a collection in the database using its schema defined in the "structure" collection.
###Overwrite dynamic rest controllers
In the skelleton project, under api/controllers folder, create a file controller.js Create a class which extends the drapi rest controller
const RestController = require('drapi').restController;
class CustomaController extends RestController {
constructor() {
super({
name: "custom",
routerPrefix: "/custom"
});
}
test(){
ctx.body = "custom route"
}
registerRouter_() {
//Add custom routes above super.registerRouter_()
// this.router_.get('/test', (ctx) => this.test(ctx));
super.registerRouter_();
}
}
module.exports = CustomaController;
###Overwrite rest methods
const RestController = require('drapi').restController;
class CustomaController extends RestController {
constructor() {
super({
name: "custom",
routerPrefix: "/custom"
});
}
list(ctx){
//list logic here
}
detail(ctx){
//detail logic here
}
create(ctx){
//create logic here
}
upd(ctx){
//upd logic here
}
softdel(ctx){
//softdel logic here
}
del(ctx){
//del logic here
}
registerRouter_() {
//Add custom routes above super.registerRouter_()
// this.router_.get('/test', (ctx) => this.test(ctx));
super.registerRouter_();
}
}
module.exports = CustomaController;
###Overwrte before and after hooks
const RestController = require('drapi').restController;
class CustomaController extends RestController {
constructor() {
super({
name: "custom",
routerPrefix: "/custom"
});
}
/*
* Hooks
* Return true to continue
* Return false to stop execution
* to throw error use ctx.throw(<status>, "message")
*/
beforeCreate(ctx){
//logic here
ctx.throw(400, "message");
return false;
}
beforeUpdate(ctx){
//logic here
return true;
}
beforeDelete(ctx){
//logic here
}
afterCreate(ctx){
//logic here
ctx.throw(400, "message");
return false;
}
afterUpdate(ctx){
//logic here
return true;
}
afterDelete(ctx){
//logic here
}
}
module.exports = CustomaController;
Contribution guidelines
- Writing tests
- Code review
- Other guidelines
Who do I talk to?
- Estratek: [email protected]