Restify-Hapi - Fast and simple RESTful API builder for Hapi
A RESTful API generator plugin for the hapi framework utilizing the mongoose ODM, hapi-swagger and joi.
Super simple and yet very powerful
restify-hapi is designed to be the simplest and fasted way possible to make RESTful APIs out of a mongoose schema definition. It is a hapi plugin intended to abstract the work involved in setting up API routes/validation/handlers/documentation/etc. for the purpose of fast app development without boilerplate code.
Define your (mongoose) schema for your resource only once and reuse it (for joi). This enforces a strict and explicit API definition which, together with hapi-swagger, evaluates in a very detailed API documentation.
Table of contents
- Installation
- Example
- Default Routes
- Supported Data Types
- Pagination
- Query Pipeline
- Aggregation Pipeline
- Configuration Options
- Testing
- Swagger
- Tools
Installation
This module was implemented and tested with:
- NPM version 3.10.8
- node version 4.x
- mongodb version 3.x
- mongoose version 4.x
I do not know how this module will behave with other configurations.
$ npm install restify-hapi
Example
This is the example we use in the test hapi-server.
// first require all mongoose models because they might be referenced // in the restify method ; ; const options = User: routes: findAll: populate: false Company: single: "company" multi: "companies" hasMany: // employees (users) are destroyed when this company is destroyed // however in this case we apply the archive policy. This means // that we do not remove the resources but mark them as _archived=true fieldName: "employees" destroy: true archive: enabled: true ; server;
If you enable the archive feature then you have to make sure that your mongoose schemas specify the used archive attribute field (per default this is set to _archived
)
Default Routes
Method | Path | Information |
---|---|---|
GET | /resources | list all resources (Pagination, Query-Pipeline and Aggregation Pipeline are available) |
GET | /resources/{id} | list resource details (Aggregation Pipeline is available) |
POST | /resources | create a new resource |
PUT | /resources/{id} | update a resource |
PUT | /resources | bulk update multiple resources |
DELETE | /resources/{id} | delete a resource |
DELETE | /resources | bulk delete multipe resources |
Supported Data Types
The User Schema summarizes all supported data-types and validations.
const UserSchema = name: type: String match: /.*/ email: type: String minlength: 3 maxlength: 20 required: true default: "example@user.com" binary: type: Buffer required: true default: "default buffer" living: type: Boolean required: true default: false password: type: String required: true minlength: 8 updated: type: Date default: now min: dummyDate required: true age: type: Number min: 18 max: 65 required: true default: 20 mixed: type: SchemaTypesMixed required: true default: "test" enum: "test" "test1" "test2" array: arrayTwo: type: Array required: true min: 2 max: 5 ofString: String ofNumber: type: Array required: true min: 2 default: 1 2 ofDates: Date ofBuffer: Buffer ofBoolean: Boolean ofMixed: type: SchemaTypesMixed min: 2 ofObjectId: SchemaTypesObjectId nested: stuff: type: String lowercase: true trim: true otherStuff: type: Number required: true company: type: Number ref: "Company" required: true _archived: type: Boolean required: true default: false ;
Pagination
Pagination works with the limit
and offset
parameters
limit
specify how many results to displayoffset
specify at which position to start fetching the data in mongodb (skip)
Example:
?limit=10&offset=5 skipps the first 5 documents and fetches the next 10 in the mongodb collection
Query Pipeline
restify-hapi
provides query-paremeters out-of-the-box for almost every mongoose data type. The model attributes are suffixed with Query
. You can query as following:
single value
e.g. nameQuery=Johnarray value
e.g. nameQuery=["John", "Doe"]valid mongodb query
e.g. nameQuery={"name": {"$eq": "John"}}
The query pipeline is not available for all routes. Please refere to Default Routes for more information.
Aggregation Pipeline
restify-hapi
also provides an interface to select only certain fields and to sort by fields
sort
comma separated values (prefix with-
for dsc sort). E.g. sort=-archived,nameproject
select only a subset of fields. Works the same way as sort
Configuration Options
The default options (in this case for the sample company
resource) are as follows. You can overwrite all attribute values as long as they are valid for a hapi-server and as long as they conform to the joi-schema specification of the config object defined in baseConfig).
single
how this resource's single name should be (per default derived from the mongoose schema name)multi
how this resource's multi name should be (per default single name + s)hasMany
specify the has-many relationship options (this is optional. You can specify references without specifying any options here. In this case the destroy is set to false)fieldName
the attribute name in the mongoose schema which references the reference modeldestroy
whether to remove the referenced resources if this resource is removed (default is false)archive
(only works if destroy is set to true)enabeld
whether mark the resource asarchived
or to remove it from the collection upon removalattribute
if archive policy is enabled the you can specify the attribute field name which should be used in the schema to mark this resource as archived (default is _archived). You have to make sure that the specified attribute field name exists on the schema, otherwise the library will throw an error
routes
RESTful CRUD operations for this resourceenabled
whether to use this route or not (default set to true)password
settings for the password attribute in the payload of this routeskipXXX
you should not alter this settingsauth
authentication settings on route-layer
auth
authentication settings on root-layer (will be applied for routes which have no auth settings specified). Must be a valid hapi authentication settingprefix
used as api prefixpopulate
whether to populate reference resources or notarchive
global archive policy
Testing
Clone the package, install the dependencies, and then run:
$ npm test // runs the unit tests$ npm run test-cover // module test-coverage report$ npm run test-server // starts the test hapi-server located under ./tests/server.js
Swagger
You can use hapi-swagger to document the auto-generated API. All restified resources will have a very detailed swagger api documentation.
Exapmle configuration:
const swaggerOptions = info: "title": "API Documentation" "version": Packversion "basePath": "/api" "pathPrefixSize": 3 ; server;
Tools
Pagination, query pipeline, and aggregation pipeline make use of the modules stored in the tools folder. You can use these tools also for resources which are not restified and which are manually added to the hapi-srever. These ensures that you paging, querying and all aggregations work the same way for those resources aswell. Please refere to the code for doc.
Module | Method | Description |
---|---|---|
Enhancer | addMetaCollection | adds the links (first, prev, self, next, last), total, and count information to a collection |
Enhancer | addMetaResource | adds the links (self) information to a single resource |
Parser | parse | parses the offset, limit, project, sort, and queries parameters |
Security | hashPassword | hash the given password with bcrypt |
Security | comparePasswords | compare a password with a hashedPassword for equality |
Validator | validatePassword | validates the given password against the specified options |
Validator | generateRandomPassword | generates a sample password |