manjar v0.5.0
Manjar
Manjar is an MVC Framework like Rails for NodeJs on top of HapiJs v17.6.0 and Mongoose v5.3.6.
The main objective is to let you create a full REST API writing as little as possible. In order to do that, you need to follow some coding and file structure conventions but with the ability to be overwritten.
Installing
To use Manjar you need to set up an empty project yourself (for now) and add Manjar as a dependency.
npm i -s manjar mongo-in-memory
Setup
Create an app.js
file:
const MongoInMemory = require('mongo-in-memory');
const Manjar = require('manjar');
const MongoServer = new MongoInMemory();
MongoServer.start((error, config) => {
Manjar.init();
});
And add the following script in package.json
"scripts": {
"start": "node app.js",
...
}
Now you should be able to start the application server by:
npm start
Database Connection
Currently, Manjar is only capable of connecting to a Mongo DB Instance on localhost:27017
. Configurations to come soon MANJAR-3
Model Schemas
Manjar lets you specify your model schemas and automatically create a Mongoose Model for each and let them available for use in Endpoints or Services.
In order to create your first Model Schema you have to follow this folder structure:
api
schemas
app.js
package.json
Inside api/schemas
folder you can create as many schema files as you like and can also be grouped into several different folders within the main folder.
For api/schemas/user.js
example model schema file a User
model will be created in Mongoose.
module.exports = {
firstName: { type: String, required: true },
lastName: { type: String, required: true }
};
Model name will be the filename with the first letter capitalized
All Mongoose Schema Definitions are valid on this kind of files
API Endpoints
Manjar lets you specify your API Endpoints and automatically route requests to each of them.
In order to create your first API Endpoint you have to follow this folder structure:
api
endpoints
app.js
package.json
Inside api/endpoints
folder you can create as many endpoint files as you like and can also be grouped into several different folders within the main folder.
For api/endpoints/health.js
example API endpoint file a GET /health
route will be automatically wired to the Hapi Server.
module.exports = {
handler: async (req, h) => {
return 'ok';
}
}
Any handler receives the req
request param and h
response handler as any normal Hapi Handler would and works exactly the same way
Also, if you want to use any of your models, you can access them from the injected Manjar parameter in all endpoints. An example api/endpoints/users/user.getAll.js
endpoint file which creates a GET /users
route demonstrate how you could use the User
model defined.
module.exports = Manjar => {
const { User } = Manjar.Models;
return {
handler: async (req, h) => {
return await User.find({});
}
};
};
Automatic Routes
Manjar has a default behavior that wires any endpoint file defined in api/endpoints
folder to a constructed <METHOD> /<PATH>
route.
The following rules are applied when generating the <METHOD>
and the <PATH>
values:
- METHOD value is:
- GET for files that end with
.getAll.js
- GET for files that end with
.get.js
- POST for files that end with
.post.js
- PUT for files that end with
.put.js
- PATCH for files that end with
.patch.js
- DELETE for files that end with
.delete.js
- GET for files that end with
- PATH value is:
/model
for files likeapi/endpoints/model/model.getAll.js
/model
for files likeapi/endpoints/model/model.post.js
/model/{id}
for files likeapi/endpoints/model/model.get.js
/model/{id}
for files likeapi/endpoints/model/model.put.js
/model/{id}
for files likeapi/endpoints/model/model.patch.js
/model/{id}
for files likeapi/endpoints/model/model.delete.js
/file
for files likeapi/endpoints/file.js
/folder/file
for files likeapi/endpoints/folder/file.js
/folder/subfolder/file
for files likeapi/endpoints/folder/subfolder/file.js
If for some reason you are not satisfied with the automatically generated route, you can always override this values in your endpoint file
module.exports = {
method: 'POST',
path: '/something-unexpected',
handler: async (req, h) => {
return 'ok';
}
}