TypeORM
A simple model:
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
}
The ORM
FoalTS uses TypeORM as default Object-Relational Mapping. This allows you to create classes to interact with your database tables (or collections). TypeORM is written in TypeScript and supports both Active Record and Data Mapper patterns.
Here is a non-exhaustive list of its features:
- migrations and automatic migrations generation
- uni-directional, bi-directional and self-referenced relations
- eager and lazy relations
- TypeScript support
- connection configuration in json / xml / yml / env formats
- transactions
- etc
Although this documentation presents the basic features of TypeORM, you may be interested in reading the official documentation to learn more advanced features.
Supported Databases
FoalTS supports officially the following databases:
Database | Versions | Driver |
---|---|---|
PostgreSQL | 9.6+ (Version Policy) | pg@8 |
MySQL | 5.7+ (Version Policy) | mysql@2 |
SQLite | 3 | sqlite3@5 |
MongoDB | 4.0+ (Version Policy) | mongodb@5 |
Use with FoalTS
TypeORM is integrated by default in each new FoalTS project. This allows you to quickly create models, run migrations and use the authentication system without wasting time on configuration. However, if you do not wish to use it, you can refer to the page Using another ORM.
Initial Configuration
When creating a new project, an SQLite
database is used by default as it does not require any additional installation (the data is saved in a file). The connection configuration is stored in default.json
located in the config/
directory.
Packages
npm install typeorm@0.3.17 @foal/typeorm
Two packages are required to use TypeORM with FoalTS:
- The package typeorm which is the official one of the ORM. It includes everything you need to create models and make database requests.
- The package @foal/typeorm (maintained by FoalTS) which contains additional components. These are particularly useful when using FoalTS authentication and authorization system.
Database Configuration Examples
PostgreSQL
npm install pg
config/default.{json|yml|js}
- YAML
- JSON
- JS
# ...
database:
type: postgres
host: localhost
port: 5432
username: root
password: password
database: my-db
{
// ...
"database": {
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "root",
"password": "password",
"database": "my-db"
}
}
module.exports = {
// ...
database: {
type: "postgres",
host: "localhost",
port: 5432,
username: "root",
password: "password",
database: "my-db"
}
}
MySQL
npm install mysql
config/default.{json|yml|js}
- YAML
- JSON
- JS
# ...
database:
type: mysql
host: localhost
port: 3306
username: root
password: password
database: my-db
{
// ...
"database": {
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "password",
"database": "my-db"
}
}
module.exports = {
// ...
database: {
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "password",
database: "my-db"
}
}
Configuration and Testing
When running the command npm run test
with the above configuration, FoalTS will try to retrieve the database configuration in this order:
config/test.yml
andconfig/test.json
.config/default.yml
andconfig/default.json
.
In this way, you can define a default configuration in the config/default.{yml|json}
file to use both during development and testing and override some settings in config/test.{yml|json}
during testing.
You learn more on how configuration works in Foal here
In the example below, we add two new options:
dropSchema
clears the database each time we create the connection- and
synchronize
synchronizes the database tables with your entities so your do not have to generate and run migrations during testing.
config/test.yml
# ...
database:
username: 'test'
password: 'test'
database: 'test'
dropSchema: true
sychronize: true
Example of a test
import { DataSource } from 'typeorm';
import { createDataSource } from '../db';
describe('xxx', () => {
let dataSource: DataSource;
beforeEach(async () => {
dataSource = createDataSource();
await dataSource.initialize();
});
afterEach(async () => {
if (dataSource) {
await dataSource.destroy()
}
});
it('yyy', () => {
// ...
});
});