Skip to main content
Version: v3

REST API

Example:

foal generate rest-api product --register

Building a REST API is often a common task when creating an application. To avoid reinventing the wheel, FoalTS provides a CLI command to achieve this.

foal generate rest-api <name> [--register] [--auth]

This command generates three files: an entity, a controller and the controller's test. Depending on your directory structure, they may be generated in different locations:

  • in the directories src/app/controllers and src/app/entities if they exist
  • or in the directories controllers and entities.

The generated controller already has a set of implemented routes that you can customize as you like. It defines a REST API and is ready to use. The only thing to do is to connect the controller to the AppController or one of its children.

The --register option automatically registers your controller in the AppController.

The API Behavior

Below is a table summarizing how the generated API works:

HTTP MethodCRUDEntire Collection (e.g. /products)Specific Item (e.g. /products/{id})
GETRead200 (OK) - list of products200 (OK) - the product
404 (Not Found)
POSTCreate201 (Created) - the created product
400 (Bad Request) - the validation error
Not implemented
PUTUpdate/ReplaceNot implemented200 (OK) - the updated product
400 (Bad Request) - the validation error
404 (Not Found)
PATCHUpdate/ModifyNot implemented200 (OK) - the updated product
400 (Bad Request) - the validation error
404 (Not Found)
DELETEDeleteNot implemented204 (No Content)
404 (Not Found)

The GET /<name>s routes also accept two optional query parameters skip and take to handle pagination. If the parameters are not valid numbers, the controller responds with a 400 (Bad Request) status.

  • skip - offset from where items should be taken.
  • take - max number of items that should be taken.

Example:

GET /products?skip=10&take=20

The Resource and its Representation

Once your API is set up, you can define its attributes.

The entity generated by default should look like this:

import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Product extends BaseEntity {

@PrimaryGeneratedColumn()
id: number;

@Column()
text: string;

}

And the schema of your API (defined in the controller file) should look like this:

export const productSchhema = {
additionalProperties: false,
properties: {
text: { type: 'string', maxLength: 255 },
},
required: [ 'text' ],
type: 'object',
};

The entity is the resource. It is the database model used internally on the server.

The schema is the representation of the resource. It defines the interface of the API.

In simple scenarios, the two are very similar but they can differ much more in complex applications. A resource may have several representations and it may be made of several entities.

How to Add New Field

For example, if you want to add a sold boolean field whose default value is false, you can do the following:

product.entity.ts

import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Product extends BaseEntity {

@PrimaryGeneratedColumn()
id: number;

@Column()
text: string;

@Column()
sold: boolean;

}

product.controller.ts

export const productSchhema = {
additionalProperties: false,
properties: {
sold: { type: 'boolean', default: false },
text: { type: 'string', maxLength: 255 },
},
required: [ 'text' ],
type: 'object',
};

Using Authentication

If you wish to attach a user to the resource, you can use the --auth flag to do so.

Example:

foal generate rest-api product --auth

This flags adds an owner: User column to your entity and uses it in the API.

Generating OpenAPI documentation

The generated controllers also have OpenAPI decorators on their methods to document the API.

In this way, when the configuration key settings.openapi.useHooks is set to true, we can get a full documentation of the API using Swagger UI

Example of documentation.