Skip to the content.

Cortadito

A small module that makes building WebApps and API services with Express quick.

Features

Setup and First WebApp

  1. Follow these steps to get started with your first Cortadito webapp:
mkdir test-app
cd test-app
npm init
npm install express --save
npm install cortadito --save
mkdir -p application/models
mkdir -p application/controllers
mkdir -p application/views
mkdir -p application/adapters
mkdir -p application/public

At some point this will be automated by a script, for now, it will involve some keystrokes.

  1. Create a sample controller (application/controllers/sample.mjs) with some endpoints:
export default function sample(controller) {
	controller.get('/', async (request, response) => {
		const hi = await Promise.resolve('Hi! I ran async.')
		response.send(hi)
	})

	controller.get('/fail', async (request, response) => { // eslint-disable-line no-unused-vars
		await Promise.reject(new Error('REJECTED!'))
	})

	controller.get('/denied', async (request, response) => {
		response.status(403).send('Not here')
	})

	controller.get('/set', (request, response) => {
		request.session.timestamp = Date.now()
		response.json({session: request.session})
	})

	controller.get('/get', (request, response) => {
		response.json({session: request.session})
	})
}

This should be familiar to any Express user.

  1. Add an entry point index.js on the root folder. This contains your app options and can be configurable via env-vars for container usage:
#!/usr/bin/env node

import process from 'node:process'
import Cortadito from 'cortadito'
import sample from './application/controllers/sample.mjs'

const options = {
	listenPort: process.env.PORT // Mandatory
}

const app = new Cortadito()
await app.configure(options)
app.addRoute('/', sample)
app.addDefaultHandlers()
app.start()

This creates the application based on the options, then takes the sample controller and adds it to the document root. Other controllers will have their own route/path. The HTTP 404 and 500 handling is added via the addDefaultHandlers method. Finally the app starts on the listenPort specified.

Other options, as follows (showing default values):

const options = {
	listenPort: process.env.PORT, // Mandatory!
	applicationRoot: process.cwd() // Path to application structure
	loggerFormat: 'common' // Morgan formats
	viewEngine: 'ejs', // Any views supported by Express5
	sessionRedisUrl: "redis://......", // Used for Session Storage
	sessionSecret: "<hard secret>", // Used for Session Storage
	redirectSecure: false // Redirects to HTTPS if on HTTP
}

The error handling can be customized to return plain JSON, HTTP codes or an EJS rendered page, your choice as follows:

// REMOVE app.addDefaultHandlers()
app.addMiddleware((request, response, _) => {
	response.status(404).render('error', {
		pageTitle: 'File Not Found',
		status: 404,
		message: 'Sorry! The path you specified doesn\'t exist.',
		stack: request.url
	})
})
app.addMiddleware((error, request, response, next) => {
	if (response.headersSent) {
		// Headers already sent, can't change the status
		return next(error)
	}

	response.status(500).render('error', {
		pageTitle: 'Oops!',
		status: 500,
		message: error.message || error,
		stack: request.app.get('env') === 'development' ? error.stack : ''
	})
})

A sample repo can be cloned or templated with the code above at: cortadito-sample.

Docker Support

Add the following file to the root folder and docker build:

FROM node:latest

WORKDIR /app
ADD . /app

RUN npm install

CMD ["npm","start"]

Also Checkout

  1. EJS Templates - this is what the views use
  2. Express - this is what powers the HTTP communication