RESTHapi Gen
RESTHapi Gen is a @hapijs/hapi plugin which generates a CRUD RESTful API from a given joi model.
Compatibility
RESTHapi Gen version | Hapi JS version | Joi Version |
---|---|---|
2.x.x and 3.x.x
|
20.x.x and 21.x.x
|
joi^17.x.x |
1.x.x |
19.x.x |
@hapi/joi^17.x.x |
0.x.x |
18.x.x |
@hapi/joi^15.x.x |
TL;DR;
$ npm i @hapi/hapi joi mongoose rest-hapi-gen
const Hapi = require('@hapi/hapi');
const Joi = require('joi');
const Mongoose = require('mongoose');
const RestHapiGen = require('rest-hapi-gen');
(async () => {
await Mongoose.connect('mongodb://localhost:27017/testdb', { useNewUrlParser: true, useUnifiedTopology: true });
const server = Hapi.server({ port: 4000 });
const petsCollectionConf = {
collection: { name: 'pets' },
schema: Joi.object({
name: Joi.string().required(),
tags: Joi.array().items(Joi.string()).default([]),
}),
};
await server.register([{ plugin: RestHapiGen, options: petsCollectionConf }]);
await server.start();
console.log('Server running on %s', server.info.uri);
})();
Plugin configuration
Option | Type | Description |
---|---|---|
auth.enabled | boolean |
Optional Whether to activate auth or not. Default: false
|
auth.client.id | string |
Required OAuth 2.0 client id. It is required if $.auth.enabled === true
|
auth.client.secret | string |
Required OAuth 2.0 client secret. It is required if $.auth.enabled === true
|
auth.client.kind | string |
Optional OAuth 2.0 server kind. Default: keycloak
|
auth.scope.read | string[] |
Optional OAuth 2.0 required scope list to access read actions. Default false
|
auth.scope.write | string[] |
Optional OAuth 2.0 required scope list to access write actions. Default false
|
auth.server.url | string |
Required OAuth 2.0 server. It is required if $.auth.enabled === true
|
auth.server.realm | string |
Optional OAuth 2.0 server realm. Default: master
|
auth.session.cookie.name | string |
Optional Name for the session cookie. Default: rest-hapi-gen-session
|
auth.session.enabled | boolean |
Optional Whether to enable session or just bearer only auth mechanism. Default: true
|
auth.session.password | string |
Optional The session encryption password. Default: Random generated |
basePath | string |
Optional Base path where the CRUD endpoints are attached. Default: '/'
|
collection.name | string |
Required Name for the collection that is going to be created. |
collection.pages.limit | number |
Optional Default max limit for collection queries, it will be overrided if the API user uses collection?limit=x . Default: 10
|
health.enabled | boolean |
Optional Whether to enable a health endpoint. Default: true
|
health.path | string |
Optional Target path where the health endpoint will be set, it must start with / . Default: /_healthz
|
overrides.actions.GET_COLLECTION | Function |
Optional Async function that will override the default handler for GET_COLLECTION action |
overrides.actions.GET_RESOURCE | Function |
Optional Async function that will override the default handler for GET_RESOURCE action |
overrides.actions.CREATE_RESOURCE | Function |
Optional Async function that will override the default handler for CREATE_RESOURCE action |
overrides.actions.UPDATE_RESOURCE | Function |
Optional Async function that will override the default handler for UPDATE_RESOURCE action |
overrides.actions.DELETE_RESOURCE | Function |
Optional Async function that will override the default handler for DELETE_RESOURCE action |
rootPathRedirect | boolean |
Optional Whether redirect from root path (/ ) to basePath path. Default: false
|
schema | Joi |
Required Joi schema for the collection that is created. |
tls | boolean |
Optional Whether the server is using TLS externally/internally or not. Default: false
|
Override an action
If an action needs to be overrided, you must provide an async function
that will be executed instead of the default one. This function will receive three args: request
that will be a @hapijs/hapi request object, h
that will be a @hapijs/hapi request toolkit and a model
that will be a mongoose model which is based on the given schema.
NOTE: Your custom function must return an object that must to be valid against the Joi schema otherwise the server will return an internal server error.
...
const { ActionType } = RestHapiGen;
...
const petsCollectionConf = {
collection: { name: 'pets' },
schema: Joi.object({
name: Joi.string().required(),
tags: Joi.array().items(Joi.string()).default([])
}),
// Override actions
overrides: {
actions: {
// Override GET collection action
[ActionType.GET_COLLECTION]: async (request, h, model) => {
return await model.find();
},
},
},
};
...
In addition, you could configure Hapi server adding debug.request
so you can see schema validation errors, to do so you must apply the following configuration to your Hapi server
...
const server = Hapi.server({
port: 4000,
debug: {
request: ['*'],
},
});
...
Configure authentication
Currently, RESTHapi Gen only support keycloak
as authentication provider, a generated resource can be protected using OAuth 2.0 and keycloak server, see the following example.
const petsCollectionConf = {
collection: { name: 'pets' },
schema: Joi.object({
name: Joi.string().required(),
tags: Joi.array().items(Joi.string()).default([]),
}),
auth: {
enabled: true,
server: { url: 'https://auth.example.io', realm: 'pets' },
client: { id: 'example-client', secret: 'example-client-secret' },
scope: { read: ['pets:ro'], write: ['pets:rw'] },
},
};
Deploy MongoDB
Docker
$ docker run -d --rm --name mymongo -p 27017:27017 mongo
Docker Compose
version: '3.7'
services:
mongo:
image: mongo
ports:
- 27017:27017
$ curl -sSL https://raw.githubusercontent.com/dani8art/rest-hapi-gen/master/docker-compose.yaml > docker-compose.yaml
$ docker-compose up -d
License
RESTHapi Gen is MIT licensed.