Skip to main content

Features

We have identified what we believe are the essential building blocks of a modern serverless backend and have tied them together with instantly deployable Node.js/JavaScript code managed by an easy to use CLI tool and the web-based Studio application.
Codehooks has similar uses as many other cloud or backend services: building and deploying APIs, storing and retrieving data, integrating systems and so on. However, our focus is primarily on providing a cost-effective and tightly integrated set of essential components which enables unprecedented speed and simplicity for developers.
  1. Serverless Node.js Express-like backend with automatic CRUD REST API built in
  2. NoSQL document database with MongoDB-like queries
  3. Studio - a user friendly web-based application for querying and managing data
  4. Fast Key-Value store
  5. Simple Worker Queues
  6. Scheduled background jobs controlled by CRON expressions
  7. Easy Authentication of APIs using JWKS

Serverless Node.js Express-like backend with automatic CRUD REST API built in

Use the power of JavaScript (or TypeScript) and Node.js NPM just like in any ExpressJS project. Directly within the API handler functions, you have access to the NoSQL document database, the Key-Value store and the Worker Queues (see the description of these features below). The combination of these features lets you easily build sophisticated data processing logic for your APIs with very little code and setup. The entire backend application is deployed with a single command coho deploy, which only takes a few seconds.

When you create a project, we automatically create a 'dev' space and deploys a complete CRUD backend using the codehooks-crudlify library. You can use the API right away and later add other routes or schema/validation.
// ...
// examples of all handlers available for API creation

app.use(fooMiddleware); // global middleware - intercept calls like like ExpressJS
app.get('/ping', (req, res) => {
res.json({ "message": "Pong!"});
});
app.get('/foo', getFooFunc); // HTTP GET event handler
app.get('/foo/:id', getOneFooFunc); // HTTP GET event handler(one)
app.post('/foo', postFooFunc); // HTTP POST event handler
app.put('/foo/:id', putFooFunc); // HTTP PUT event handler
app.patch('/foo/:id', patchFooFunc); // HTTP PATCH event handler
app.delete('/foo/:id', deleteFooFunc); // HTTP DELETE event handler
app.all('/foo', allFooFunc); // handle all GET, POST, PUT, PATCH, DELETE
app.auth('/foo', fooMiddlewareFunc); // custom auth for API route /foo

export default app.init();

NoSQL document database with MongoDB-like queries

The NoSQL JSON document database is available inside the JavaScript serverless backend functions directly without any connection string or setup. The database is powered by the open source database engine RocksDB, providing a blazing fast performance even for huge datasets (using indexes). We provide a MongoDB-like syntax to query the database and also convenience methods to easily stream data through the serverless backend API endpoints. Data can be imported and exported from/to JSON and CSV formats using the CLI or the web-based Studio application (see below).
import { app, Datastore } from 'codehooks-js'

async function updateDevice(req, res) {
const conn = await Datastore.open();
// TODO: validate input ;-)
const data = await conn.updateOne('devices', req.params.id, req.body);
res.json(data);
}
// .../device?search=raspberry
async function findDevices(req, res) {
const conn = await Datastore.open();
const { search } = req.query;
const filter = {"name" : {$regex : `${search}`, $options: "i"}}
const options = {
limit: 100,
filter,
}
conn.getMany('devices', options).json(res); // stream result
}
// HTTP API routes and handlers
app.patch('/device/:id', updateDevice);
app.get('/device', findDevices);

export default app.init();

Studio for simple data management

In your account on account.codehooks.io, you can add projects, spaces and collections (and soon backend code). Each space comes with a user-friendly web-based application which lets you quickly interact with your NoSQL database for creating, querying, updating and deleting objects. You can also quickly import large CSV or JSON files using the Studio.

Fast Key-Value store

Sometimes you need to store and lookup data using custom keys, not database ids like in a NoSQL document database. A data cache, a JWT token or user session, a counter... the use cases are many. We have embedded a simple key-value store which lets you easily persist data. The values can be retrieved with single keys or using a key pattern to fetch multiple values. Using key patterns, you can also stream the result through an API endpoint.
import { app, Datastore } from 'codehooks-js'

app.get('/ticket/:id', async (req, res) => {
const conn = await Datastore.open();
const { id } = req.params;
// get the ticket from the key-value store
const ticket = await conn.get(`ticket-${id}`);
if (!ticket) { return res.status(404).json({ error: 'Ticket not found'});}
// increase counter by 1
const retrieveCount = await conn.incr(`ticket-count-${id}`, 1);
res.json({ ticket, retrieveCount });
});

app.post('/ticket', async (req, res) => {
const { transactionid, email } = req.body;
const conn = await Datastore.open();
const ticket = await someNiceFunctionForCreatingATicket(transactionid, email); // implemented elsewhere ;)
// store the ticket in the key-value store
conn.set(`ticket-${ticket.id}`, ticket);
res.status(201).json({ ticket });
});

export default app.init();

Simple Worker Queues

Backends sometimes need to process data asynchronously to handle longer running tasks. By using a persistent queue, an API call can return immediately and let the queue worker do it's job at its own pace. For instance, an API call could receive the order to create a ticket PDF and then put the job of creating the ticket-PDF into a queue and return an OK response to the web client. When the queue worker script is finished it would send out an email with the ticket.
import { app, Datastore } from 'codehooks-js'

app.worker('ticketToPDF', (req, res) => {
const { email, ticketid } = req.body.payload;
//TODO: implement code to fetch ticket data, produce PDF
// and send email with attachment using Mailgun, Sendgrid or Amazon SES
// ...and implement error handling
res.end(); // done processing queue item
})

app.post('/createticket', async (req, res) => {
const { email, ticketid } = req.body;
const conn = await Datastore.open();
await conn.enqueue("ticketToPDF", { email, ticketid });
res.status(201).json({"message": `Ticket will be generated and sent to ${email}`});
})

export default app.init();

Scheduled background jobs controlled by CRON expressions

When you need to run some code at specific times and intervals, you need a scheduled background job. It's basically just a function which runs whenever you want it to, specified by a CRON expression. Let's say you need to send out a newsletter each morning at 8AM or you need to process the transactions each evening at 9PM or you need to scan a webpage every 5 minutes for some updates. A job hook is your go to tool for these kinds of...eh...jobs.
import { app, Datastore } from 'codehooks-js'
import * as cheerio from 'cheerio';
import fetch from 'node-fetch';

const scrapePlayerScoringStats = async () => {
// TODO: implement the web scraper using cheerio
return result;
}

// run every evening at 23:00 (11pm)
// use https://crontab.guru to learn more about CRON
app.job('0 23 * * *', async (req, res) => {
const playerStats = await scrapePlayerScoringStats();
const conn = await Datastore.open();
for(let result of playerStats){
conn.set(`player-${result.player}`, result.goals);
}
})

Easy Authentication of APIs using JWKS

How do you authenticate an API? In modern web applications, users get redirected to a login page to prove their identity using a social provider or username/password. They are then redirected back and the application receives some form of access token which is exchanged with a JWT token for use with the application. This token is then sent with each API call and must be verified by the backend. With codehooks.io, the backend developer can add a JWKS endpoint and codehooks.io will verify the tokens for you. You can override authentication using the `app.auth` event handler if you need to.