Skip to main content
Version: 1.x

Architecture Overview

FoalTS is a framework for creating server-side Node.js applications. It is written in TypeScript, a typed superset of JavaScript that provides advanced development tools and the latest language features.

FoalTS architecture is organized around three main components: controllers, services and hooks.


Controllers are classes instantiated as singletons. Their methods process the incoming HTTP requests.

import { Get, HttpResponseOK } from '@foal/core';
class AppController {
  @Get('/')  index() {    return new HttpResponseOK('Hello world!');  }


Services are also classes instantiated as singletons. They are used by the controllers (or hooks) to perform specific tasks.

import { dependency, Get, HttpResponseOK } from '@foal/core';
class AppController {  @dependency  logger: Logger;
  @Get('/')  index() {    this.logger.log('index has been called!');    return new HttpResponseOK('Hello world!');  }
class Logger {  log(message: string) {    console.log(`${new Date()} - ${message}`);  }}


Hooks are small functions that add extra logic before or after the execution of a controller method.

import { Get, HttpResponseOK } from '@foal/core';import { JWTRequired } from '@foal/jwt';
class AppController {
  @Get('/')  @JWTRequired()  index() {    return new HttpResponseOK('Hello world!');  }

A Simple Application#

Controllers may have sub-controllers. Hooks can be attached to the controllers or their methods.

Here's an example of what a FoalTS application may look like.

import { Context, Get, HttpResponseNotFound, HttpResponseOK, Log } from '@foal/core';import { JWTRequired } from '@foal/jwt';
@JWTRequired()class ApiController {  private products = [    { id: 1, name: 'phone' },    { id: 2, name: 'computer' },  ]
  @Get('/products')  listProducts() {    return new HttpResponseOK(this.products);  }
  @Get('/products/:id')  getProduct(ctx: Context) {    const product = this.products.findOne(      p => ===    );
    if (!product) {      return new HttpResponseNotFound();    }
    return new HttpResponseOK(product);  }}
@Log('Receiving a request...')class AppController {  subControllers = [    controller('/api', ApiController)  ];
  @Get('/')  index() {    return new HttpResponseOK('Welcome!');  }}

Request Lifecycle