Skip to content

Commit 6c5cb40

Browse files
committed
scaffold of two more microservices as example, customers and payments
1 parent 0c03b31 commit 6c5cb40

30 files changed

+408
-4
lines changed
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { CustomersController } from './customers.controller';
3+
import { CustomersService } from './customers.service';
4+
5+
describe('CustomersController', () => {
6+
let customersController: CustomersController;
7+
8+
beforeEach(async () => {
9+
const app: TestingModule = await Test.createTestingModule({
10+
controllers: [CustomersController],
11+
providers: [CustomersService],
12+
}).compile();
13+
14+
customersController = app.get<CustomersController>(CustomersController);
15+
});
16+
17+
describe('root', () => {
18+
it('should return "Hello World!"', () => {
19+
expect(customersController.getHello()).toBe('Hello World!');
20+
});
21+
});
22+
});

Diff for: server/apps/customers/src/customers.controller.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Controller } from '@nestjs/common';
2+
import { MessagePattern } from '@nestjs/microservices';
3+
import { findAllCustomersCommand } from '@vsp/common';
4+
import { CustomersService } from './customers.service';
5+
6+
@Controller()
7+
export class CustomersController {
8+
constructor(private readonly customersService: CustomersService) {}
9+
10+
@MessagePattern(findAllCustomersCommand)
11+
public async findAllPayments(): Promise<any[]> {
12+
return [];
13+
}
14+
}

Diff for: server/apps/customers/src/customers.module.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Module } from '@nestjs/common';
2+
import { CustomersController } from './customers.controller';
3+
import { CustomersService } from './customers.service';
4+
5+
@Module({
6+
imports: [],
7+
controllers: [CustomersController],
8+
providers: [CustomersService],
9+
})
10+
export class CustomersModule {}

Diff for: server/apps/customers/src/customers.service.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Injectable } from '@nestjs/common';
2+
3+
@Injectable()
4+
export class CustomersService {
5+
getHello(): string {
6+
return 'Hello World!';
7+
}
8+
}

Diff for: server/apps/customers/src/main.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { NestFactory } from '@nestjs/core';
2+
import { TcpOptions, Transport } from '@nestjs/microservices';
3+
import { EnvironmentService } from '@vsp/core';
4+
import { loadEnvironmentVariables } from '@vsp/env';
5+
import { CustomersModule } from './customers.module';
6+
7+
// Load env file from NODE_ENV
8+
loadEnvironmentVariables('./environments');
9+
10+
async function bootstrap() {
11+
const environmentService: EnvironmentService = new EnvironmentService();
12+
const app = await NestFactory.createMicroservice(
13+
CustomersModule, {
14+
transport: Transport.TCP,
15+
options: {
16+
host: environmentService.get('CUSTOMERS_SERVICE_HOST') || 'localhost',
17+
port: environmentService.get('CUSTOMERS_SERVICE_PORT') || 3001
18+
}
19+
} as TcpOptions
20+
);
21+
await app.listen();
22+
}
23+
bootstrap();

Diff for: server/apps/customers/test/app.e2e-spec.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { INestApplication } from '@nestjs/common';
3+
import * as request from 'supertest';
4+
import { CustomersModule } from './../src/customers.module';
5+
6+
describe('CustomersController (e2e)', () => {
7+
let app: INestApplication;
8+
9+
beforeEach(async () => {
10+
const moduleFixture: TestingModule = await Test.createTestingModule({
11+
imports: [CustomersModule],
12+
}).compile();
13+
14+
app = moduleFixture.createNestApplication();
15+
await app.init();
16+
});
17+
18+
it('/ (GET)', () => {
19+
return request(app.getHttpServer())
20+
.get('/')
21+
.expect(200)
22+
.expect('Hello World!');
23+
});
24+
});

Diff for: server/apps/customers/test/jest-e2e.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"moduleFileExtensions": ["js", "json", "ts"],
3+
"rootDir": ".",
4+
"testEnvironment": "node",
5+
"testRegex": ".e2e-spec.ts$",
6+
"transform": {
7+
"^.+\\.(t|j)s$": "ts-jest"
8+
}
9+
}

Diff for: server/apps/customers/tsconfig.app.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"declaration": false,
5+
"outDir": "../../dist/apps/customers"
6+
},
7+
"include": ["src/**/*"],
8+
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { CustomersController } from './customers.controller';
3+
4+
describe('CustomersController', () => {
5+
let controller: CustomersController;
6+
7+
beforeEach(async () => {
8+
const module: TestingModule = await Test.createTestingModule({
9+
controllers: [CustomersController],
10+
}).compile();
11+
12+
controller = module.get<CustomersController>(CustomersController);
13+
});
14+
15+
it('should be defined', () => {
16+
expect(controller).toBeDefined();
17+
});
18+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Controller, Get, Inject, UseGuards } from '@nestjs/common';
2+
import { ClientProxy, RpcException } from '@nestjs/microservices';
3+
import { catchError, Observable, throwError } from 'rxjs';
4+
5+
import { CUSTOMERS_SERVICE_TOKEN, findAllCustomersCommand } from '@vsp/common';
6+
import { LoggerService } from '@vsp/logger';
7+
import { JwtAuthGuard } from '@vsp/authorization';
8+
9+
@Controller('customers')
10+
export class CustomersController {
11+
@Inject(CUSTOMERS_SERVICE_TOKEN)
12+
private readonly _customersServiceClient: ClientProxy;
13+
14+
constructor(private readonly _logger: LoggerService) {
15+
this._logger.setContext(CustomersController.name);
16+
}
17+
18+
@Get()
19+
@UseGuards(JwtAuthGuard)
20+
public findAllCustomers(): Observable<any[]> {
21+
return this._customersServiceClient
22+
.send(findAllCustomersCommand, {})
23+
.pipe(catchError(error => throwError(() => new RpcException(error.response))));
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { PaymentsController } from './payments.controller';
3+
4+
describe('PaymentsController', () => {
5+
let controller: PaymentsController;
6+
7+
beforeEach(async () => {
8+
const module: TestingModule = await Test.createTestingModule({
9+
controllers: [PaymentsController],
10+
}).compile();
11+
12+
controller = module.get<PaymentsController>(PaymentsController);
13+
});
14+
15+
it('should be defined', () => {
16+
expect(controller).toBeDefined();
17+
});
18+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Controller, Get, Inject, UseGuards } from '@nestjs/common';
2+
import { ClientProxy, RpcException } from '@nestjs/microservices';
3+
import { catchError, Observable, throwError } from 'rxjs';
4+
5+
import { PAYMENTS_SERVICE_TOKEN, findAllPaymentsCommand } from '@vsp/common';
6+
import { LoggerService } from '@vsp/logger';
7+
import { JwtAuthGuard } from '@vsp/authorization';
8+
9+
@Controller('payments')
10+
export class PaymentsController {
11+
@Inject(PAYMENTS_SERVICE_TOKEN)
12+
private readonly _paymentsServiceClient: ClientProxy;
13+
14+
constructor(private readonly _logger: LoggerService) {
15+
this._logger.setContext(PaymentsController.name);
16+
}
17+
18+
@Get()
19+
@UseGuards(JwtAuthGuard)
20+
public findAllPayments(): Observable<any[]> {
21+
return this._paymentsServiceClient
22+
.send(findAllPaymentsCommand, {})
23+
.pipe(catchError(error => throwError(() => new RpcException(error.response))));
24+
}
25+
}

Diff for: server/apps/gateway/src/gateway.module.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { LoggerModule } from '@vsp/logger';
77

88
import { AuthController } from './controllers/auth.controller';
99
import { AccountsController } from './controllers/accounts.controller';
10-
import { identityMicroserviceProvider } from './gateway.providers';
10+
import { customersMicroserviceProvider, identityMicroserviceProvider, paymentsMicroserviceProvider } from './gateway.providers';
1111
import { LocalStrategy } from './strategies/local.strategy';
1212

1313
import { JwtStrategy } from './strategies/jwt.strategy';
14+
import { PaymentsController } from './controllers/payments.controller';
15+
import { CustomersController } from './controllers/customers.controller';
1416

1517

1618
@Module({
@@ -22,10 +24,14 @@ import { JwtStrategy } from './strategies/jwt.strategy';
2224
],
2325
controllers: [
2426
AuthController,
25-
AccountsController
27+
AccountsController,
28+
PaymentsController,
29+
CustomersController
2630
],
2731
providers: [
2832
identityMicroserviceProvider,
33+
customersMicroserviceProvider,
34+
paymentsMicroserviceProvider,
2935
JwtStrategy,
3036
LocalStrategy,
3137
],

Diff for: server/apps/gateway/src/gateway.providers.ts

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ClientProxyFactory, TcpClientOptions, Transport } from '@nestjs/microservices';
22

3-
import { IDENTITY_SERVICE_TOKEN } from '@vsp/common';
3+
import { CUSTOMERS_SERVICE_TOKEN, IDENTITY_SERVICE_TOKEN, PAYMENTS_SERVICE_TOKEN } from '@vsp/common';
44
import { EnvironmentService } from '@vsp/core';
55

66
export const identityMicroserviceProvider = {
@@ -16,3 +16,31 @@ export const identityMicroserviceProvider = {
1616
},
1717
inject: [EnvironmentService]
1818
};
19+
20+
export const paymentsMicroserviceProvider = {
21+
provide: PAYMENTS_SERVICE_TOKEN,
22+
useFactory: (environmentService: EnvironmentService) => {
23+
return ClientProxyFactory.create({
24+
options: {
25+
port: environmentService.get('PAYMENTS_SERVICE_PORT'),
26+
host: environmentService.get('PAYMENTS_SERVICE_HOST'),
27+
},
28+
transport: Transport.TCP,
29+
} as TcpClientOptions);
30+
},
31+
inject: [EnvironmentService]
32+
};
33+
34+
export const customersMicroserviceProvider = {
35+
provide: CUSTOMERS_SERVICE_TOKEN,
36+
useFactory: (environmentService: EnvironmentService) => {
37+
return ClientProxyFactory.create({
38+
options: {
39+
port: environmentService.get('CUSTOMERS_SERVICE_PORT'),
40+
host: environmentService.get('CUSTOMERS_SERVICE_HOST'),
41+
},
42+
transport: Transport.TCP,
43+
} as TcpClientOptions);
44+
},
45+
inject: [EnvironmentService]
46+
};

Diff for: server/apps/payments/src/main.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { NestFactory } from '@nestjs/core';
2+
import { TcpOptions, Transport } from '@nestjs/microservices';
3+
import { EnvironmentService } from '@vsp/core';
4+
import { loadEnvironmentVariables } from '@vsp/env';
5+
import { PaymentsModule } from './payments.module';
6+
7+
// Load env file from NODE_ENV
8+
loadEnvironmentVariables('./environments');
9+
10+
async function bootstrap() {
11+
const environmentService: EnvironmentService = new EnvironmentService();
12+
const app = await NestFactory.createMicroservice(
13+
PaymentsModule, {
14+
transport: Transport.TCP,
15+
options: {
16+
host: environmentService.get('PAYMENTS_SERVICE_HOST') || 'localhost',
17+
port: environmentService.get('PAYMENTS_SERVICE_PORT') || 3001
18+
}
19+
} as TcpOptions
20+
);
21+
await app.listen();
22+
}
23+
bootstrap();

Diff for: server/apps/payments/src/payments.controller.spec.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { PaymentsController } from './payments.controller';
3+
import { PaymentsService } from './payments.service';
4+
5+
describe('PaymentsController', () => {
6+
let paymentsController: PaymentsController;
7+
8+
beforeEach(async () => {
9+
const app: TestingModule = await Test.createTestingModule({
10+
controllers: [PaymentsController],
11+
providers: [PaymentsService],
12+
}).compile();
13+
14+
paymentsController = app.get<PaymentsController>(PaymentsController);
15+
});
16+
17+
describe('root', () => {
18+
it('should return "Hello World!"', () => {
19+
expect(paymentsController.getHello()).toBe('Hello World!');
20+
});
21+
});
22+
});

Diff for: server/apps/payments/src/payments.controller.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Controller, Get } from '@nestjs/common';
2+
import { MessagePattern } from '@nestjs/microservices';
3+
import { findAllPaymentsCommand } from '@vsp/common';
4+
import { PaymentsService } from './payments.service';
5+
6+
@Controller()
7+
export class PaymentsController {
8+
constructor(private readonly paymentsService: PaymentsService) {}
9+
10+
@MessagePattern(findAllPaymentsCommand)
11+
public async findAllPayments(): Promise<any[]> {
12+
return [];
13+
}
14+
}

Diff for: server/apps/payments/src/payments.module.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Module } from '@nestjs/common';
2+
import { PaymentsController } from './payments.controller';
3+
import { PaymentsService } from './payments.service';
4+
5+
@Module({
6+
imports: [],
7+
controllers: [PaymentsController],
8+
providers: [PaymentsService],
9+
})
10+
export class PaymentsModule {}

Diff for: server/apps/payments/src/payments.service.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Injectable } from '@nestjs/common';
2+
3+
@Injectable()
4+
export class PaymentsService {
5+
getHello(): string {
6+
return 'Hello World!';
7+
}
8+
}

Diff for: server/apps/payments/test/app.e2e-spec.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { INestApplication } from '@nestjs/common';
3+
import * as request from 'supertest';
4+
import { PaymentsModule } from './../src/payments.module';
5+
6+
describe('PaymentsController (e2e)', () => {
7+
let app: INestApplication;
8+
9+
beforeEach(async () => {
10+
const moduleFixture: TestingModule = await Test.createTestingModule({
11+
imports: [PaymentsModule],
12+
}).compile();
13+
14+
app = moduleFixture.createNestApplication();
15+
await app.init();
16+
});
17+
18+
it('/ (GET)', () => {
19+
return request(app.getHttpServer())
20+
.get('/')
21+
.expect(200)
22+
.expect('Hello World!');
23+
});
24+
});

0 commit comments

Comments
 (0)