Lightweight, minimalistic approach to RESTful endpoints in express.
Get up and running with a fully functioning CRUD API, with minimum configuration. Get all the functionality of a fully loaded framework with only the smallest amount of configuration.
The hobson framework follows a RESTful approach. It uses models to define database relations and resources to provide endpoints to query the database.
- Provides commonly used CRUD endpoints out of the box
- Easily add and configure endpoints
- Endpoints take a protected by default approach to ensure security
- Provides stateless authentication using tokens
- Mongoose is used to provide great schema validation, hooks, etc.
- Before and after hooks are provided
- Easily integrates with existing express apps
Get started by installing hobson.
npm install --save hobson
Hobson uses mongoose under the hood as it gives us awesome schema validation features.
Hobson is straight forwards in that it has 2 main types of components; models and resources. Models handle data interations and resources provide easy to use API endpoints.
Step 1. Create a model with a schema
File: unicorn.model.js
const { Schema } = require('hobson');
const unicornSchema = Schema({
shape: {
owner: {
type: mongoose.Schema.ObjectId,
ref: 'User', // same as userResource.name
required: true,
},
name: {
type: String,
required: true,
},
},
options: {
timestamps: false,
},
});
// unicornSchema is a mongoose schema which means you can create virtuals, methods, etc. on it.
unicornSchema.virtual('today').get(() => Date.now());
module.exports = unicornSchema.compile('Unicorn'); // returns the Unicorn model
Step 2. Create a resource from a model
File: unicorn.resource.js
const { Resource } = require('hobson');
const Unicorn = require('./unicorn.model.js');
const unicornResource = new Resource({ model: Unicorn });
// route configuration here...
module.exports = unicornResource;
Step 3. Connect to your express app
File: app.js
const hobson = require('hobson');
const app = require('express')();
// add middlewares and configurations to express app...
hobson.attach({
app,
secret: process.env.SUPER_SECRET_FOR_AUTHENTICATION,
resources: [
unicornResource,
// others...
],
});
All endpoints have a unique string ID by which you can use to access them. To access an resource's endpoint, use the get
method.
unicornResource.get('findById');
To overwrite an endpoint, simply provide your endpoint configuration with the same ID value.
The hobson resource creates endpoints for you like you would on a regular RESTful API.
ID | Method | Endpoint | Example |
---|---|---|---|
find |
get | /unicorns |
/unicorns?filter[color]=purple |
count |
get | /unicorns/count |
/unicorns/count?filter[color]=yellow |
findOne |
get | /unicorns/one |
/unicorns/one?include=horns |
findById |
get | /unicorns/:unicornId |
/unicorns/5a8ed7fabf4aabad60e41247 |
create |
post | /unicorns |
/unicorns |
update |
patch | /unicorns/:unicornId |
/unicorns/5a8ed7fabf4aabad60e41247 |
remove |
delete | /unicorns/:unicornId |
/unicorns/5a8ed7fabf4aabad60e41247 |
Here is how you add custom endpoints to the resource.
File: unicorn.resource.js
const findGreenUnicons = new Route({
id: 'findGreenUnicons',
path: '/green',
methods: 'get',
handler: async () => console.log('do things here'),
});
unicornResource.add(findGreenUnicorns);
Routes are protected by default. Provide permission functions to give access to your users.
File: unicorn.resource.js
unicornResource.get('findGreenUnicorns')
.access(({ user }) => {
return user.role === ROLE_ADMIN; // access given to only admins
});
Provide hooks to your endpoints which will run before and after the main handler. There is also a helpful context
object which you can use to assign data to access throughout your function chain.
File: unicorn.resource.js
unicornResource.get('findGreenUnicorns')
.before(({ context }) => {
context.appendMessage = 'Hi Fred,';
})
.after(({ data, context }) => {
console.log(context.appendMessage, data); // Hi Fred, Yo mama!
});
You can also use old express middleware too. When added, these will run before all the other functions.
File: unicorn.resource.js
unicornResource.get('findGreenUnicorns')
.middleware((req, res, next) => {
req.example = 'Hello there!';
next(); // important: make sure to call next
});
Endpoints should return information in a specific format so that it is easy to read on the client.
The following standards are inspired by the work done on JSend. See there standards here.
{
"status": "success",
"code": 200,
"data": {
"unicorns": [
{
"_id": "110297391319273",
"content": "This is a good unicorn.",
},
{
"_id": "110297391319273",
"content": "This is another unicorn.",
}
],
}
}
{
"status": "fail",
"code": 400,
"message": "There was a validation error.",
"data": {
"title": {
"message": "Path `title` is required.",
"kind": "required",
"path": "title",
},
"magic.wands": {
"message": "Path `magic.wands` (10) is less than minimum allowed value (1000).",
"kind": "min",
"path": "magic.wands",
"value": 10,
}
}
}
{
"status": "error",
"code": 500,
"message": "The server pooped itself.",
}
MIT