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, options)
- app.job(cronExpression, workerFunction)
- app.static(options, callback)
- app.storage(options, callback)
- app.crudlify(schema, options)
- app.createWorkflow(name, desc, workflowJSON)
- app.set(key, val)
- app.internalFetch(url, options)
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, options)
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)
- options: (optional) Object with configuration settings
- workers: number - Number of parallel workers to process queue items concurrently. Limited by your plan quota.
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: '/', directory: '/dist', default: 'index.html', notFound: '/index.html' })
Options
- route: URL sub route for clients
- directory: path to file upload directory
- default: (optional) default file to serve when requesting a directory (e.g., 'index.html')
- notFound: (optional) file to serve for 404 errors (essential for client-side routing in SPAs)
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();
app.set(key, val)
Set configuration settings for the application. This allows you to configure various aspects of your application behavior.
Parameters
- key: String - the configuration key
- val: any - the configuration value
Returns void
Code example
import { app } from 'codehooks-js';
import handlebars from 'handlebars';
// Set views directory
app.set('views', '/views');
// Set view engine
app.set('view engine', { hbs: handlebars });
// Set other configuration options
app.set('foo', 'bar');
export default app.init();
app.internalFetch(url, options)
Fetch data from another Codehooks API. This method is designed for high speed app-to-app communication within the Codehooks platform, allowing you to make authenticated API calls to other Codehooks applications.
Authentication: Must include x-apikey header for authentication if the target API is not public.
Parameters
- url: String - URL to fetch from (e.g.,
http://myapi-ffee.codehooks.io/dev/api/myroute) - options: Object (optional) - Fetch options including method, headers, body, etc.
Returns Promise<any> - Promise that resolves with the fetched data
Code example
import { app } from 'codehooks-js';
app.get('/fetch-data', async (req, res) => {
try {
// Fetch data from another Codehooks API
const data = await app.internalFetch(
'http://myapi-ffee.codehooks.io/dev/api/users',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-apikey': 'your-target-api-key-here'
}
}
);
res.json({ success: true, data });
} catch (error) {
res.status(500).json({ error: 'Failed to fetch data' });
}
});
app.post('/sync-user', async (req, res) => {
try {
// POST data to another Codehooks API
const result = await app.internalFetch(
'http://userservice-1234.codehooks.io/dev/api/users',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-apikey': 'your-target-api-key-here'
},
body: JSON.stringify(req.body)
}
);
res.json({ success: true, result });
} catch (error) {
res.status(500).json({ error: 'Failed to sync user' });
}
});
export default app.init();
Read more in the detailed workflow API docs