# TypeORM Contributors are welcome

This tutorial provide two way to create connection:

  • The first one use @tsed/typeorm module to creation multiple connections with ,
  • The seconds use the new async provider feature introduced in v5.27 to create connection.

Additionally, this topic show you how you can use Entity from Typeorm with Ts.ED controller (on bottom of this page).

TIP

You can find a working example on TypeORM here.

# Feature

Currently, @tsed/typeorm allows you:

  • Configure one or more TypeORM connections via the @ServerSettings configuration. All databases will be initialized when the server starts during the server's OnInit phase.
  • Use the Entity TypeORM as Model for Controllers, AJV Validation and Swagger.
  • Declare connection with asyncProvider or automatically by server configuration.

# Installation

To begin, install the TypeORM module for TS.ED:

npm install --save @tsed/typeorm
npm install --save typeorm
1
2

Then import @tsed/typeorm in your :

import {ServerLoader, ServerSettings} from "@tsed/common";
import "@tsed/typeorm"; // import typeorm ts.ed module

@ServerSettings({
  typeorm: [
    {
      name: "default",
      type: "postgres",
      // ...,

      entities: [
        `${__dirname}/entity/*{.ts,.js}`
      ],
      migrations: [
        `${__dirname}/migrations/*{.ts,.js}`
      ],
      subscribers: [
        `${__dirname}/subscriber/*{.ts,.js}`
      ]
    },
    {
      name: "mongo",
      type: "mongodb"
      // ...
    }
  ]
})
export class Server extends ServerLoader {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# TypeORMService

TypeORMService let you to retrieve an instance of TypeORM Connection.

import {AfterRoutesInit, Injectable} from "@tsed/common";
import {TypeORMService} from "@tsed/typeorm";
import {Connection} from "typeorm";
import {User} from "../models/User";

@Injectable()
export class UsersService implements AfterRoutesInit {
  private connection: Connection;

  constructor(private typeORMService: TypeORMService) {

  }

  $afterRoutesInit() {
    this.connection = this.typeORMService.get("mongoose")!; // get connection by name
  }

  async create(user: User): Promise<User> {
    // do something
    // ...
    // Then save
    await this.connection.manager.save(user);
    console.log("Saved a new user with id: " + user.id);

    return user;
  }

  async find(): Promise<User[]> {
    const users = await this.connection.manager.find(User);
    console.log("Loaded users: ", users);

    return users;
  }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

For more information about TypeORM look his documentation here;

# Declare your connection as provider

It also possible to create your connection with useAsyncFactory feature (See custom providers) This approach allow to inject your connection as a Service to another one.

To create a new connection, declare your custom provider as follow:

import {Configuration, registerProvider} from "@tsed/di";
import {createConnection} from "@tsed/typeorm";
import {Connection, ConnectionOptions} from "typeorm";

export const CONNECTION = Symbol.for("CONNECTION"); // declare your own symbol
export type CONNECTION = Connection; // Set alias types (optional)

const CONNECTION_NAME = "default"; // change the name according to your server configuration

registerProvider({
  provide: CONNECTION,
  deps: [Configuration],
  async useAsyncFactory(configuration: Configuration) {
    const settings = configuration.get<ConnectionOptions[]>("typeorm")!;
    const connectionOptions = settings.find(o => o.name === CONNECTION_NAME);

    return createConnection(connectionOptions!);
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Then inject your connection to another service or provide like this:

import {Inject, Injectable} from "@tsed/di";
import {CONNECTION} from "./typeorm-async-provider";

@Injectable()
export class UserService {
  constructor(@Inject(CONNECTION) connection: CONNECTION) {

  }
}
1
2
3
4
5
6
7
8
9

# Use Entity TypeORM with Controller

We need to define an Entity TypeORM like this and use Ts.ED Decorator to define the JSON Schema.

import {Maximum, MaxLength, Minimum, Property, Required} from "@tsed/common";
import {Column, Entity, PrimaryGeneratedColumn} from "typeorm";

@Entity()
export class User {

  @PrimaryGeneratedColumn()
  @Property()
  id: number;

  @Column()
  @MaxLength(100)
  @Required()
  firstName: string;

  @Column()
  @MaxLength(100)
  @Required()
  lastName: string;

  @Column()
  @Minimum(0)
  @Maximum(100)
  age: number;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

Now, the model is correctly defined and can be used with a Controller, AJV validation, Swagger and TypeORM.

We can use this model with a Controller like that:

import {BodyParams, Controller, Get, Post} from "@tsed/common";
import {User} from "../entities/User";
import {UsersService} from "../services/UsersService";

@Controller("/users")
export class UsersCtrl {
  constructor(private usersService: UsersService) {
  }

  @Post("/")
  create(@BodyParams() user: User): Promise<User> {
    return this.usersService.create(user);
  }

  @Get("/")
  getList(): Promise<User[]> {
    return this.usersService.find();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# EntityRepository

TypeORM provide EntityRepository to manipulate an Entity. TsED provide a decorator to declare for both TypeORM and TsED. This decorator is useful if you have to inject the repository to another TsED service, controller or provider.

TIP

Since v5.39.1, isn't necessary to use EntityRepository from Ts.ED. The TypeORM DI is used by Ts.ED DI to resolve injected repository to another class annotated by , , , , etc...

Here a quick example:

import {EntityRepository} from "@tsed/typeorm";
import {Repository} from "typeorm";
import {User} from "../entity/User";

@EntityRepository(User)
export class UserRepository extends Repository<User> {

}
1
2
3
4
5
6
7
8

Then inject your repository to another service:

import {Inject, Injectable} from "@tsed/di";
import {UserRepository} from "./repository/UserRepository";

@Injectable()
export class OtherService {
  constructor(userRepository: UserRepository) {

  }
}
1
2
3
4
5
6
7
8
9