Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
120 lines (85 sloc) 2.5 KB

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

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

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

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 => p.id === ctx.request.params.id
    );

    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

You can’t perform that action at this time.