Hami ( to give ) is a module that uses mongoose models to create CRUD rest endpoints as well as socket events using express.js. This creates endpoints such as
- Get one record ✔️
- Get many records ✔️
- Get record by ID ✔️
- Get records count 🧪
- Create One record ✔️
- Create Many records ✔️
- Update One record ✔️
- Update many records ✔️
- Delete one record ✔️
- Delete many records ✔️
- Live events [ onUpdate, onCreate, onDelete ] ✔️🧪
- hooks [ pre, post ]
- custom routes
- sync
We first pass in the express app into createHami like so const hami = createHami(app)
. This will setup hami up so that
can be ready to start generating routes and live events for your mongoose models hami(routes)
/models/record-model.js
const {model} = require('mongoose')
const {hamiSchema} = require('hami-express')
const RecordSchema = hamiSchema({
displayName: String,
group: { type:String, enum: ['average', 'awesome'], default: '' }
})
exports.RecordModel = model('record', RecordSchema)
Note hamiSchema({...})
is a helper function that adds timestamps for createdAt
, updatedAt
and deletedAt
. eg.
const record = hamiSchema({...})
is the same as
const record = new Schema({
...,
deletedAt: {type: Date}
}, {timestamp: true})
/routes.js
const {RecordModel} = require('./models/record-model')
module.exports = [
{model: RecordModel},
]
const express = require('express')
const {connect} = require('mongoose')
const bodyParser = require('body-parser')
const {createHami} = require('hami-express')
const routes = require('./routes')
const startTestServer = async () => {
// connecting to mongodb URI
await connect(MONGODB_URI, {
useCreateIndex: true,
useFindAndModify: true,
useNewUrlParser: true,
useUnifiedTopology: true
})
const app = express()
// required to parse json payload
app.use(bodyParser.json())
// creating routes on hami
// returns http server
const hami = createHami(app)
const server = hami(routes)
return server
}
startTestServer()
.then(server => {
server.listen(SERVER_PORT, () => {
console.log('Server started on port', SERVER_PORT)
})
})
.catch(err => {
console.error(err)
})
- Method -
GET
- Query -
{ filter: MongoDbQuery }
- Method -
GET
- Query -
{ filter: MongoDbQuery }
- Method -
GET
- Query -
{ filter: MongoDbQuery, sort: MongooseSortObject, limit: Number }
- Method -
GET
- Param -
RecordID
- Method -
POST
- body -
Record
- Method -
POST
- body -
[Record]
- Method -
UPDATE
- Query -
{ filter: MongoDbQuery }
- body -
Record
- Method -
UPDATE
- Query -
{ filter: MongoDbQuery, sort: MongooseSortObject, limit: Number }
- body -
UpdateRecord
- Method -
DELETE
- Query -
{ filter: MongoDbQuery }
- Method -
DELETE
- Query -
{ filter: MongoDbQuery }
This feature is experimental since I do not know how to achieve this without passing arguments for filtering the events, But if you know of a better way don't hesitate sharing or creating a PR.
First you will need to inject socket.io into hami as a dependency as socketServer.
const socketServer = require('socket.io')
const {createHami} = require('hami-express')
...
const hami = createHami(app)
const server = hami(routes, { socketServer })
...
There are three types of events you can subscribe to. These are
- records:create - When a record is created
- records:update - When a record is updated
- records:delete - When a record is deleted
To listen to events, you must first emit a message to your hami-express server which subscribes you for getting events.
The format for the events are the model names in plural and the hook. Example, if the model name is
bakery
and the hook you want is create
, Then the event would be bakeries:create
.
A MongoDBQuery
can be passed as an argument to filter what events to receive.
Now, to listen to the event, calling on records:created
, will send you an event when a record is being created. Note to listen to the event,
use the past tense of the hook. Bellow is the mapping for the listeners
- records:create = records:created
- records:update = records:updated
- records:delete = records:deleted
Example
const listenToRecords = async (callback) => {
const socket = io(HAMI_EXPRESS_URL)
// Subscribe
socket.on('connect', ()=>{
socket.emit('records:create', { group: { $eq: 'awesome' } })
})
// Listen
socket.on('records:created', callback)
// To disconnect when done listening
return socket.disconnect
}
const stopListeningToRecords = listenToRecords(({event, data})=>{
console.log(event) // records:created
console.log(data) // [ Records ]
})
// disconnect
stopListeningToRecords()
Note, the same version of socket.io used on the server should be the same used on the client. Otherwise, the socket connection won't work.