Skip to content

Cheat Sheet โ€‹

๐Ÿš€ Server & Configuration โ€‹

ts
import {Configuration, Inject} from "@tsed/di";
import {PlatformApplication} from "@tsed/platform-http";
import * as controllers from "./controllers/index.js";

@Configuration({
  port: 3000,
  logger: true,
  mount: [...Object.values(controllers)]
})
export class Server {
  @Inject()
  protected app: PlatformApplication;
}

๐ŸŽฏ Simple Controller โ€‹

ts
import {Controller} from "@tsed/di";
import {Get} from "@tsed/schema";

@Controller("/hello")
export class HelloController {
  @Get("/")
  get() {
    return {message: "Hello world"};
  }
}

๐Ÿงฉ Service Injection โ€‹

ts
import {Injectable} from "@tsed/di";

@Injectable()
export class MyService {
  greet(name: string): string {
    return `Hello, ${name}!`;
  }
}
ts
import {Get} from "@tsed/schema";
import {Controller, Inject} from "@tsed/di";

@Controller("/hello")
export class HelloController {
  @Inject()
  protected myService: MyService;

  @Get("/")
  get() {
    return {message: this.myService.greet("World")};
  }
}

๐Ÿ“ฅ Retrieving Parameters โ€‹

ts
import {Controller} from "@tsed/di";
import {Get, Post} from "@tsed/schema";
import {PathParams, QueryParams, BodyParams, HeaderParams} from "@tsed/platform-params";

@Controller("/users")
export class UserController {
  @Get("/:id")
  getById(@PathParams("id") id: string, @QueryParams("expand") expand?: boolean) {
    // ...
  }

  @Post("/")
  create(@BodyParams() user: any, @HeaderParams("x-api-key") apiKey: string) {
    // ...
  }
}

๐Ÿ›ก๏ธ Custom middleware โ€‹

ts
import {Middleware} from "@tsed/platform-middlewares";
import {Context} from "@tsed/platform-params";
import {Unauthorized} from "@tsed/exceptions";

@Middleware()
export class AuthMiddleware {
  async use(@Context() ctx: Context): Promise<void> {
    const token = ctx.request.headers["authorization"];
    if (!token) {
      throw new Unauthorized("Token required");
    }
  }
}

๐Ÿงช Validating with @tsed/schema โ€‹

Using decorators โ€‹

ts
import {Property, Required} from "@tsed/schema";

class UserModel {
  @Required()
  @Property()
  name: string;

  @Property()
  email?: string;
}

@Controller("/")
class MyController {
  @Post("/")
  create(@BodyParams() user: UserModel) {
    // validation automatique
  }
}

Using a schema โ€‹

ts
import {object, string} from "@tsed/schema";

const UserSchema = object({
  name: string().required().description("User's name"),
  email: string().description("User's email")
}).label("UserSchema");

interface User {
  name: string;
  email?: string;
}

@Controller("/")
class MyController {
  @Post("/")
  create(@BodyParams() @Schema(UserSchema) user: User) {
    // validation automatique
  }
}

Run validation manually โ€‹

ts
import {validate} from "@tsed/ajv";

// Shortcut to inject(AjvService).validate()
await validate(
  {
    name: "John Doe",
    email: "email@tsed.dev"
  },
  {type: UserModel}
);

or:

ts
import {validate} from "@tsed/ajv";

await validate(
  {
    name: "John Doe",
    email: "email@tsed.dev"
  },
  UserSchema
);

๐Ÿ”„ Lifecycle hooks in services โ€‹

Listen to service lifecycle events โ€‹

ts
import {Injectable, OnInit, OnDestroy} from "@tsed/di";

@Injectable()
export class MyService implements OnInit, OnDestroy {
  $onInit() {
    console.log("Service initialized");
  }

  $onDestroy() {
    console.log("Service destroyed");
  }
}

Emit custom events โ€‹

ts
import {$emit} from "@tsed/di";

@Injectable()
export class MyService {
  async doSomething() {
    // Do some work...

    // Emit a custom event
    $emit("myCustomEvent", {data: "Hello World"});
  }
}
MethodDescriptionSync/AsyncExample usage
$emitEmits an event synchronously to all listeners.Sync$emit("eventName", data);
$asyncEmitEmits an event asynchronously, waits for all listeners to complete.Asyncawait $asyncEmit("eventName", data);
$alterPasses a value through all listeners, each can alter the value (sync).Syncconst result = $alter("eventName", value, ...args);
$asyncAlterLike $alter, but listeners can be async and the result is awaited.Asyncconst result = await $asyncAlter("eventName", value, ...args);

๐Ÿ“š Documentation Swagger โ€‹

ts
import {Returns, Summary} from "@tsed/schema";

class MyController {
  @Get("/")
  @Summary("Return all users")
  @(Returns(200, Array).Of(UserModel))
  getAll() {
    return [];
  }
}

Enable in the server config:

ts
import "@tsed/swagger";

@Configuration({
  swagger: [
    {
      path: "/docs"
    }
  ]
})

๐Ÿง‘โ€๐Ÿ’ป Use context โ€‹

In controllers:

ts
import {Context} from "@tsed/platform-params";

@Controller("/users")
export class UserController {
  @Get("/:id")
  getById(@PathParams("id") id: string, @Context() ctx: Context) {
    // Access request/response via ctx.request and ctx.response
    return {id, userAgent: ctx.request.headers["user-agent"]};
  }
}

In services:

ts
import {Injectable, InjectContext} from "@tsed/di";
import type {PlatformContext} from "@tsed/platform-http";

@Injectable()
export class MyService {
  @InjectContext()
  protected ctx: PlatformContext;

  async doSomething() {
    const userId = this.ctx.request.headers["user-id"];

    this.ctx.logger.info(`User ID: ${userId}`);

    // Use userId for some logic
    return `User ID is ${userId}`;
  }
}

๐Ÿงช Unit tests with PlatformTest โ€‹

ts
import {PlatformTest} from "@tsed/platform-http/testing";

beforeEach(() => PlatformTest.create());
afterEach(() => PlatformTest.reset());

it("should inject service", () => {
  const service = PlatformTest.get<MyService>(MyService);
  expect(service).toBeInstanceOf(MyService);
});

๐Ÿ“ฆ Packages Overview โ€‹

PackageMain purposeNode.js/Bun.jsBrowser
@tsed/coreProvides utilities, helpers, and internal decorators used by other packages.โœ”๏ธโœ”๏ธ
@tsed/diDependency injection (IoC), service lifecycle management, injection decorators.โœ”๏ธโœ”๏ธ
@tsed/hooksAdds hooks/callbacks on the lifecycle of services and middlewares.โœ”๏ธโœ”๏ธ
@tsed/json-mapperSerialization/deserialization of JSON objects, data transformation.โœ”๏ธโœ”๏ธ
@tsed/exceptionsProvides custom HTTP exception classes for error handling.โœ”๏ธโœ”๏ธ
@tsed/schemaSchema declaration, validation, and model documentation (OpenAPI/Swagger).โœ”๏ธโœ”๏ธ
@tsed/ajvConsume json-schema to validate payload (based on Ajv)โœ”๏ธโœ”๏ธ
@tsed/platform-httpGeneric HTTP implementation, platform abstraction (Express, Koa, etc.).โœ”๏ธโŒ
@tsed/platform-expressExpress.js specific integration to start the server and handle requests.โœ”๏ธโŒ
@tsed/platform-koaKoa.js specific integration to start the server and handle requests.โœ”๏ธโŒ
@tsed/platform-fastifyFastify.js specific integration to start the server and handle requests.โœ”๏ธโŒ
@tsed/platform-http/testingUtilities for unit and integration testing with PlatformTest.โœ”๏ธโŒ
@tsed/platform-paramsDecorators and logic to extract request parameters (body, query, path, headers, etc.).โœ”๏ธโŒ
@tsed/platform-routerRouting management, controller mounting, and route resolution.โœ”๏ธโŒ
@tsed/platform-middlewaresManagement, registration, and execution of middlewares in the request lifecycle.โœ”๏ธโŒ
@tsed/enginesIntegrates template engines (EJS, Pug, Handlebarsโ€ฆ) for server-side rendering.โœ”๏ธโŒ
@tsed/platform-viewsAdds support for view rendering in controllers/responses via configured engines.โœ”๏ธโŒ

๐Ÿ“ Notes โ€‹

TIP

  • In TS.ED v8, always prefer @tsed/di for injection, @tsed/schema for schema declaration and HTTP decorators.
  • @tsed/common is being deprecated in v8.
  • Asynchronous middleware without next(). Ts.ED automatically handles promises.
  • Use @tsed/platform-express (or another platform) to start the server.

Released under the MIT License.