Skip to content

Commit

Permalink
feat: add migration approach instead of autogenerate tables typeorm
Browse files Browse the repository at this point in the history
  • Loading branch information
meysamhadeli committed Dec 13, 2023
1 parent bfa4ce0 commit 7774893
Show file tree
Hide file tree
Showing 29 changed files with 156 additions and 34 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [Technologies - Libraries](#technologies---libraries)
- [The Domain and Bounded Context - Service Boundary](#the-domain-and-bounded-context---service-boundary)
- [Structure of Project](#structure-of-project)
- [How to Use Migrations](#how-to-use-migrations)
- [How to Run](#how-to-run)
- [Docker Compose](#docker-compose)
- [Support](#support)
Expand Down Expand Up @@ -137,6 +138,20 @@ I used CQRS to decompose my features into small parts that makes our application

Using the CQRS pattern, we cut each business functionality into vertical slices, for each of these slices we group classes (see [technical folders structure](http://www.kamilgrzybek.com/design/feature-folders)) specific to that feature together (command, handlers, infrastructure, repository, controllers, etc). In our CQRS pattern each command/query handler is a separate slice. This is where you can reduce coupling between layers. Each handler can be a separated code unit, even copy/pasted. Thanks to that, we can tune down the specific method to not follow general conventions (e.g. use custom SQL query or even different storage). In a traditional layered architecture, when we change the core generic mechanism in one layer, it can impact all methods.

## How to Use Migrations
> Note: For easy using of migrations commands in typeorm, I add some scripts in `package.json` and base on these scripts we can use below commands for generate and run migrations easily.
For `generating` a new migration use this command in the root of each microservice:

```bash
npm run migration:generate -- src/data/migrations/new-migration-name
```

Also for `running` migration use this command in the root of each microservice:
```bash
npm run migration:run
```

## How to Run

> ### Docker
Expand Down
5 changes: 3 additions & 2 deletions src/booking/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ POSTGRES_PORT=5432
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_Database=booking
POSTGRES_SYNCHRONIZE =true
POSTGRES_ENTITIES=src/**/entities/*.{js,ts}
POSTGRES_SYNCHRONIZE =false
POSTGRES_ENTITIES=/../**/*.entity.{js,ts}
POSTGRES_MIGRATIONS=/../**/data/migrations/*.{js,ts}

# Rabbitmq
RABBITMQ_Host=localhost
Expand Down
4 changes: 4 additions & 0 deletions src/booking/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"dev": "tsc -p tsconfig.json && nodemon src/main.ts --watch",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"typeorm": "npm run build && npx typeorm -d ./dist/data/data-source.js",
"migration:generate": "npm run typeorm -- migration:generate",
"migration:run": "npm run typeorm -- migration:run",
"migration:revert": "npm run typeorm -- migration:revert",
"test": "jest"
},
"dependencies": {
Expand Down
3 changes: 2 additions & 1 deletion src/booking/src/data/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const postgresOptions: DataSourceOptions = {
password: configs.postgres.password,
database: configs.postgres.database,
synchronize: configs.postgres.synchronize,
entities: [configs.postgres.entities],
entities: [__dirname + configs.postgres.entities],
migrations: [__dirname + configs.postgres.migrations],
logging: configs.postgres.logging,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class CreateBookingTable1702506382196 implements MigrationInterface {
name = 'CreateBookingTable1702506382196'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "booking" ("id" SERIAL NOT NULL, "flightNumber" character varying NOT NULL, "aircraftId" integer NOT NULL, "departureAirportId" integer NOT NULL, "arriveAirportId" integer NOT NULL, "flightDate" TIMESTAMP NOT NULL, "price" integer NOT NULL, "description" character varying NOT NULL, "seatNumber" character varying NOT NULL, "passengerName" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL, "updatedAt" TIMESTAMP, CONSTRAINT "PK_49171efc69702ed84c812f33540" PRIMARY KEY ("id"))`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "booking"`);
}

}
4 changes: 2 additions & 2 deletions src/building-blocks/rabbitmq/rabbitmq-connection.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/building-blocks/rabbitmq/rabbitmq-connection.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/building-blocks/rabbitmq/rabbitmq-connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class RabbitmqConnection implements OnModuleInit, IRabbitmqConnection {
}

this.channel.on("error", async (error): Promise<void> => {
Logger.error(`Error occurred on channel: ${error}`);
Logger.error(`Error occurred on channel rabbitmq: ${error}`);
await this.closeChanel();
await this.getChannel();
});
Expand Down Expand Up @@ -109,7 +109,7 @@ export class RabbitmqConnection implements OnModuleInit, IRabbitmqConnection {
);

this.connection.on("error", async (error): Promise<void> => {
Logger.error(`Error occurred on connection: ${error}`);
Logger.error(`Error occurred on connection rabbitmq: ${error}`);
await this.closeConnection();
await this.initializeConnection();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface PostgresContainerOptions {
username: string;
password: string;
synchronize: boolean;
entities: string;
}
export declare class PostgresContainer {
start(): Promise<[StartedTestContainer, DataSourceOptions]>;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'reflect-metadata';
import { GenericContainer, StartedTestContainer } from 'testcontainers';
import {Logger} from "@nestjs/common";
import configs from "../../../configs/configs";
import {DataSourceOptions} from "typeorm";

export interface PostgresContainerOptions {
Expand All @@ -13,6 +12,7 @@ export interface PostgresContainerOptions {
username: string;
password: string;
synchronize: boolean;
entities: string;
}

export class PostgresContainer{
Expand All @@ -31,8 +31,7 @@ export class PostgresContainer{
username: defaultPostgresOptions.username,
password: defaultPostgresOptions.password,
synchronize: true,
entities: [configs.postgres.entities],
logging: configs.postgres.logging,
entities: [defaultPostgresOptions.entities]
};

Logger.log(`Test postgres with port ${containerPort} established`);
Expand Down Expand Up @@ -60,7 +59,8 @@ export class PostgresContainer{
username: 'testcontainers',
password: 'testcontainers',
imageName: 'postgres:latest',
synchronize: true
synchronize: true,
entities: 'src/**/entities/*.{js,ts}'
};

return postgresOptions;
Expand Down
2 changes: 1 addition & 1 deletion src/building-blocks/tsconfig.tsbuildinfo

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/flight/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ POSTGRES_PORT=5432
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_Database=flight
POSTGRES_SYNCHRONIZE =true
POSTGRES_ENTITIES=src/**/entities/*.{js,ts}
POSTGRES_SYNCHRONIZE =false
POSTGRES_ENTITIES=/../**/*.entity.{js,ts}
POSTGRES_MIGRATIONS=/../**/data/migrations/*.{js,ts}

# Rabbitmq
RABBITMQ_Host=localhost
Expand Down
4 changes: 4 additions & 0 deletions src/flight/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"dev": "tsc -p tsconfig.json && nodemon src/main.ts --watch",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"typeorm": "npm run build && npx typeorm -d ./dist/data/data-source.js",
"migration:generate": "npm run typeorm -- migration:generate",
"migration:run": "npm run typeorm -- migration:run",
"migration:revert": "npm run typeorm -- migration:revert",
"test": "jest"
},
"dependencies": {
Expand Down
3 changes: 2 additions & 1 deletion src/flight/src/data/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const postgresOptions: DataSourceOptions = {
password: configs.postgres.password,
database: configs.postgres.database,
synchronize: configs.postgres.synchronize,
entities: [configs.postgres.entities],
entities: [__dirname + configs.postgres.entities],
migrations: [__dirname + configs.postgres.migrations],
logging: configs.postgres.logging
};

Expand Down
Loading

0 comments on commit 7774893

Please sign in to comment.