The Application Object
The Application object creates events that lets you hook your serverless functions accordingly.
Available event types are:
- REST API route events
- Background Job cron and scheduled events
- Worker Queue events
- Authentication events
The event hooks is an Node.js Express style JavaScript library in a public npm library that you install as a npm package in your project directory. You can check for updates in the npm version.
Install the CLI.
npm i codehooks-js
Deploy your app with the CLI command.
coho deploy
API quick overview
- Complete code example
- app.init()
- app.use(workerFunction)
- app.use(route, workerFunction)
- app.get(route, workerFunction)
- app.post(route, workerFunction)
- app.put(route, workerFunction)
- app.patch(route, workerFunction)
- app.delete(route, workerFunction)
- app.all(route, workerFunction)
- app.auth(route, workerFunction)
- app.worker(name, workerFunction)
- app.job(cronExpression, workerFunction)
- app.static(options, callback)
- app.storage(options, callback)
- app.crudlify(schema, options)
- app.createWorkflow(name, desc, workflowJSON)
Complete code example
Import the app
library in your application and hook into the various events.
import { app } from 'codehooks-js';
// generic serverless function
function fooFunc(req, res) {
res.end();
}
// generic middleware function
function fooMiddleware(req, res, next) {
next();
}
/*
* Hook into events
*/
app.use(fooMiddleware); // global middleware
app.use('/foo', fooMiddleware); // global middleware on routes
app.get('/foo', fooFunc); // GET
app.post('/foo', fooFunc); // POST
app.put('/foo', fooFunc); // PUT
app.patch('/foo', fooFunc); // PATCH
app.delete('/foo', fooFunc); // DELETE
app.all('/foo', fooFunc); // GET, POST, PUT, PATCH, DELETE
app.auth('/*', fooMiddleware); // Called before outher routes without access tokens
app.job('* * * * *', fooFunc); // subscribe to cron events
app.worker('workername', fooFunc); // subscribe to worker events
app.static(options); // serve deployed static files and content
app.storage(options); // serve dynamic uploaded files and content
app.crudlify(options); // Database CRUD REST API
// Bind events and functions to the serverless runtime
export default app.init();
app.init()
Mandatory call to bind your functions to events from the serverless runtime.
Parameters none
app.use(workerFunction)
Adds global middleware to all route API events (get, put, post, patch, delete).
Parameters
- workerFunction: function(requestObject, responseObject, next)
Returns void
Code example
import { app } from 'codehooks-js';
import cookieParser from 'cookie-parser';
// external npm lib middleware
app.use(cookieParser());
app.get('/foo', function (req, res) {
// Cookies that have not been signed
console.log('Cookies: ', req.cookies);
// Cookies that have been signed
console.log('Signed Cookies: ', req.signedCookies);
// Custom middleware result
console.log('Foo: ', req.foo);
res.send('Done');
});
export default app.init();
app.use(route, workerFunction)
Adds global middleware to a specific route API events (get, put, post, patch, delete).
Parameters
- route: String or RegExp that matches route
- workerFunction: function(requestObject, responseObject, next)
Returns void
Code example
import { app } from 'codehooks-js';
// custom
app.use('/foo', (req, res, next) => {
console.log('Called before any other route handlers');
req.foo = 'Foo was here!';
next(); // must be called to continue
});
app.get('/foo', function (req, res) {
// Custom middleware result
console.log('Foo: ', req.foo);
res.send('Done');
});
export default app.init();
app.get(route, workerFunction)
Execute workerFunction function on HTTP GET method and route match.
Parameters
- route: String or RegExp that matches route
- workerFunction: function(requestObject, responseObject)
Returns void
Code example
import { app } from 'codehooks-js';
app.get('/foo', function (req, res) {
res.send('Done');
});
export default app.init();
app.post(route, workerFunction)
Execute workerFunction function on HTTP POST method and route match.
Parameters
- route: String or RegExp that matches route
- workerFunction: function(requestObject, responseObject)
Returns void
Code example
import { app } from 'codehooks-js';
app.post('/foo', function (req, res) {
console.log('Data from client is', req.body);
res.send('Done');
});
export default app.init();
app.put(route, workerFunction)
Execute workerFunction function on HTTP PUT method and route match.
Parameters
- route: String or RegExp that matches route
- workerFunction: function(requestObject, responseObject)
Returns void
Code example
import { app } from 'codehooks-js';
app.put('/foo', function (req, res) {
console.log('Data from client is', req.body);
res.send('Done');
});
export default app.init();
app.patch(route, workerFunction)
Execute workerFunction function on HTTP PATCH method and route match.
Parameters
- route: String or RegExp that matches route
- workerFunction: function(requestObject, responseObject)
Returns void
Code example
import { app } from 'codehooks-js';
app.patch('/foo', function (req, res) {
console.log('Data from client is', req.body);
res.send('Done');
});
export default app.init();
app.delete(route, workerFunction)
Execute workerFunction function on HTTP DELETE method and route match.
Parameters
- route: String or RegExp that matches route
- workerFunction: function(requestObject, responseObject)
Returns void
Code example
import { app } from 'codehooks-js';
app.delete('/foo/:ID', function (req, res) {
const { ID } = req.params;
console.log('Delete this', ID);
res.send('Done');
});
export default app.init();
app.all(route, workerFunction)
If no other routes matched before this, then execute the workerFunction function on all HTTP methods and route match.
Parameters
- route: String or RegExp that matches route
- workerFunction: function(requestObject, responseObject)
Returns void
Code example
import { app } from 'codehooks-js';
app.get('/foo', function (req, res) {
res.send('Done GET');
});
app.all('/*', function (req, res) {
res.send(
`None of the above routes matched but this ${req.method} ${req.originalUrl}`
);
});
export default app.init();
app.auth(route, workerFunction)
Execute workerFunction function when no authentication token (x-apikey or JWT) is present. Works for all HTTP methods and route matches.
Parameters
- route: String or RegExp that matches route
- workerFunction: function(requestObject, responseObject)
Returns void
Code example
app.worker(name, workerFunction)
Register a named workerFunction function that can be used to process queued events or scheduled events.
Parameters
- name: unique worker name
- workerFunction: function(queueData, responseFunction)
Returns void
Code example for worker queues
Code example for scheduled workers
app.job(cronExpression, workerFunction)
Execute workerFunction function when cron job are scheduled.
Parameters
- cronExpression: a valid cron expression string
- workerFunction: function(jobData, responseFunction)
app.static(options, callback)
Serve static files from deployed source directory.
For example: app.static({ route: '/img', directory: '/assets/images' })
Options
- directory: path to file upload directory
- route: URL sub route for clients
callback(req, res, next)
Provide a middleware function to control the request. For example, add client side cache headers instructions for static assets.
// serve static assets/images, and cache for 1 hour
app.static({ route: '/assets', directory: '/assets' }, (req, res, next) => {
console.log(
'If you see this, the client cache is invalidated or called for the first time'
);
const ONE_HOUR = 1000 * 60 * 60;
res.set('Cache-Control', `public, max-age=${ONE_HOUR}, s-maxage=${ONE_HOUR}`);
res.setHeader('Expires', new Date(Date.now() + ONE_HOUR).toUTCString());
res.removeHeader('Pragma');
next();
});
app.storage(options, callback)
Serve files from the blob storage file system. You can upload files to the blob storage with the CLI. Also see the Filesystem API docs.
$ coho file-upload --projectname 'myproject-fafc' --space 'dev' --src '/mylocaldir/' --target '/mydocuments'
For example: app.storage({ route: '/docs', directory: '/mydocuments' })
Options
- directory: path to file upload directory
- route: URL sub route for clients
callback(req, res, next)
Provide a middleware function to control the request.
app.crudlify(schema, options)
Creates a complete Database REST API (detailed docs here).
Example: REST API for two collection customer
and product
, any schema is allowed:
app.crudlify({ customer: {}, product: {} }, { prefix: '/crudapi' });
// Example valid URL's
// https://myproject-ff00.api.codehooks.io/dev/customer?name=Bill
// https://myproject-ff00.api.codehooks.io/dev/product?price>42
Schema
-- collection: schema, for specific collections, e.g. {"collection": someSchema}
Options
- prefix: serve REST routes under another route.
{"prefix": "/api"}
Returns Promise to before<VERB>
after<VERB>
functions.
Example:
crudlify(app, {product, customer}).then((hooks) => {
hooks.beforePOST('customer', async (data) => {
// do something here
data.foo = 'Was here before saving!'
})
hooks.afterPOST('product', async (data) => {
console.log("Data as saved to the database", data)
// do something here
})
app.createWorkflow(name, desc, workflowJSON)
Create reliable stateful workflows using plain JavaScript.
Parameters
- name (string): Unique identifier for the workflow
- description (string): Human-readable description of the workflow
- steps (WorkflowDefinition): Object containing step definitions
Returns: Workflow instance for managing the workflow
Code example:
import { app } from 'codehooks-js';
// The workflow definition
const workflow = app.createWorkflow('minimal', 'Minimal workflow example', {
start: (state, goto) => {
goto('end', { ...state, message: 'Hello World' });
},
end: (state, goto) => goto(null, state), // null complete the workflow
});
// A REST API to start a new workflow instance
app.post('/start', async (req, res) =>
res.json(await workflow.start({ prop: 'some value' }))
);
export default app.init();
Read more in the detailed workflow API docs