mirror of
https://github.com/nestjs/nest.git
synced 2026-02-21 23:11:44 +00:00
tests(@nestjs) push basic integration tests
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,7 +24,6 @@ yarn-error.log
|
||||
|
||||
# tests
|
||||
/test
|
||||
/integration
|
||||
/coverage
|
||||
/.nyc_output
|
||||
build/config\.gypi
|
||||
18
integration/docker-compose.yml
Normal file
18
integration/docker-compose.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
redis:
|
||||
container_name: redis_integration
|
||||
image: redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
restart: always
|
||||
nats:
|
||||
container_name: nats_integration
|
||||
image: nats
|
||||
expose:
|
||||
- "4222"
|
||||
ports:
|
||||
- "8222:8222"
|
||||
- "4222:4222"
|
||||
restart: always
|
||||
21
integration/hello-world/.gitignore
vendored
Normal file
21
integration/hello-world/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDE
|
||||
/.idea
|
||||
/.awcache
|
||||
/.vscode
|
||||
|
||||
# misc
|
||||
npm-debug.log
|
||||
|
||||
# example
|
||||
/quick-start
|
||||
|
||||
# tests
|
||||
/test
|
||||
/coverage
|
||||
/.nyc_output
|
||||
|
||||
# dist
|
||||
/dist
|
||||
56
integration/hello-world/e2e/fastify-adapter.spec.ts
Normal file
56
integration/hello-world/e2e/fastify-adapter.spec.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { expect } from 'chai';
|
||||
import * as fastify from 'fastify';
|
||||
import * as request from 'supertest';
|
||||
import * as express from 'express';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { ApplicationModule } from './../src/app.module';
|
||||
import { FastifyAdapter } from '@nestjs/core/adapters/fastify-adapter';
|
||||
import { ExpressAdapter } from '@nestjs/core/adapters/express-adapter';
|
||||
import { HelloService } from '../src/hello/hello.service';
|
||||
|
||||
describe('Hello world (fastify adapter)', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [ApplicationModule],
|
||||
}).compile();
|
||||
|
||||
server = fastify();
|
||||
app = module.createNestApplication(new FastifyAdapter(server));
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`/GET`, () => {
|
||||
return server
|
||||
.inject({
|
||||
method: 'GET',
|
||||
url: '/hello',
|
||||
})
|
||||
.then(({ payload }) => expect(payload).to.be.eql('Hello world!'));
|
||||
});
|
||||
|
||||
it(`/GET (Promise/async)`, () => {
|
||||
return server
|
||||
.inject({
|
||||
method: 'GET',
|
||||
url: '/hello/async',
|
||||
})
|
||||
.then(({ payload }) => expect(payload).to.be.eql('Hello world!'));
|
||||
});
|
||||
|
||||
it(`/GET (Observable stream)`, () => {
|
||||
return server
|
||||
.inject({
|
||||
method: 'GET',
|
||||
url: '/hello/stream',
|
||||
})
|
||||
.then(({ payload }) => expect(payload).to.be.eql('Hello world!'));
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
60
integration/hello-world/e2e/guards.spec.ts
Normal file
60
integration/hello-world/e2e/guards.spec.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication, Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { ApplicationModule } from './../src/app.module';
|
||||
import { APP_GUARD } from '@nestjs/core';
|
||||
|
||||
@Injectable()
|
||||
export class Guard {
|
||||
canActivate() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AuthGuard {
|
||||
canActivate() {
|
||||
const x = true;
|
||||
if (x) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createTestModule(guard) {
|
||||
return Test.createTestingModule({
|
||||
imports: [ApplicationModule],
|
||||
providers: [
|
||||
{
|
||||
provide: APP_GUARD,
|
||||
useValue: guard,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
}
|
||||
|
||||
describe('Guards', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
it(`should prevent access (forbidden)`, async () => {
|
||||
app = (await createTestModule(
|
||||
new Guard(),
|
||||
)).createNestApplication();
|
||||
|
||||
await app.init();
|
||||
return request(app.getHttpServer())
|
||||
.get('/hello')
|
||||
.expect(403);
|
||||
});
|
||||
|
||||
it(`should prevent access (unauthorized)`, async () => {
|
||||
app = (await createTestModule(
|
||||
new AuthGuard(),
|
||||
)).createNestApplication();
|
||||
|
||||
await app.init();
|
||||
return request(app.getHttpServer())
|
||||
.get('/hello')
|
||||
.expect(401);
|
||||
});
|
||||
});
|
||||
45
integration/hello-world/e2e/hello-world.spec.ts
Normal file
45
integration/hello-world/e2e/hello-world.spec.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { ApplicationModule } from './../src/app.module';
|
||||
|
||||
describe('Hello world (default adapter)', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [ApplicationModule],
|
||||
})
|
||||
.compile();
|
||||
|
||||
app = module.createNestApplication();
|
||||
server = app.getHttpServer();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`/GET`, () => {
|
||||
return request(server)
|
||||
.get('/hello')
|
||||
.expect(200)
|
||||
.expect('Hello world!');
|
||||
});
|
||||
|
||||
it(`/GET (Promise/async)`, () => {
|
||||
return request(server)
|
||||
.get('/hello/async')
|
||||
.expect(200)
|
||||
.expect('Hello world!');
|
||||
});
|
||||
|
||||
it(`/GET (Observable stream)`, () => {
|
||||
return request(server)
|
||||
.get('/hello/stream')
|
||||
.expect(200)
|
||||
.expect('Hello world!');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
87
integration/hello-world/e2e/interceptors.spec.ts
Normal file
87
integration/hello-world/e2e/interceptors.spec.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication, Injectable } from '@nestjs/common';
|
||||
import { ApplicationModule } from './../src/app.module';
|
||||
import { APP_INTERCEPTOR } from '@nestjs/core';
|
||||
import { of } from 'rxjs/observable/of';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
const RETURN_VALUE = 'test';
|
||||
|
||||
@Injectable()
|
||||
export class OverrideInterceptor {
|
||||
intercept(data, context, stream) {
|
||||
return of(RETURN_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class TransformInterceptor {
|
||||
intercept(data, context, stream) {
|
||||
return stream.pipe(map(data => ({ data })));
|
||||
}
|
||||
}
|
||||
|
||||
function createTestModule(interceptor) {
|
||||
return Test.createTestingModule({
|
||||
imports: [ApplicationModule],
|
||||
providers: [
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useValue: interceptor,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
}
|
||||
|
||||
describe('Interceptors', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
it(`should transform response (sync)`, async () => {
|
||||
app = (await createTestModule(
|
||||
new OverrideInterceptor(),
|
||||
)).createNestApplication();
|
||||
|
||||
await app.init();
|
||||
return request(app.getHttpServer())
|
||||
.get('/hello')
|
||||
.expect(200, RETURN_VALUE);
|
||||
});
|
||||
|
||||
it(`should map response`, async () => {
|
||||
app = (await createTestModule(
|
||||
new TransformInterceptor(),
|
||||
)).createNestApplication();
|
||||
|
||||
await app.init();
|
||||
return request(app.getHttpServer())
|
||||
.get('/hello')
|
||||
.expect(200, { data: 'Hello world!' });
|
||||
});
|
||||
|
||||
it(`should map response (async)`, async () => {
|
||||
app = (await createTestModule(
|
||||
new TransformInterceptor(),
|
||||
)).createNestApplication();
|
||||
|
||||
await app.init();
|
||||
return request(app.getHttpServer())
|
||||
.get('/hello/stream')
|
||||
.expect(200, { data: 'Hello world!' });
|
||||
});
|
||||
|
||||
it(`should map response (stream)`, async () => {
|
||||
app = (await createTestModule(
|
||||
new TransformInterceptor(),
|
||||
)).createNestApplication();
|
||||
|
||||
await app.init();
|
||||
return request(app.getHttpServer())
|
||||
.get('/hello/async')
|
||||
.expect(200, { data: 'Hello world!' });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
28
integration/hello-world/package.json
Normal file
28
integration/hello-world/package.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "nest-typescript-starter",
|
||||
"version": "1.0.0",
|
||||
"description": "Nest TypeScript starter repository",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "ts-node src/main"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^4.3.0",
|
||||
"@nestjs/core": "^4.3.0",
|
||||
"@nestjs/microservices": "^4.3.0",
|
||||
"@nestjs/testing": "^4.3.0",
|
||||
"@nestjs/websockets": "^4.3.0",
|
||||
"class-transformer": "^0.1.7",
|
||||
"class-validator": "^0.7.2",
|
||||
"fastify": "^1.1.1",
|
||||
"redis": "^2.7.1",
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"rxjs": "^5.4.3",
|
||||
"typescript": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^7.0.41",
|
||||
"supertest": "^3.0.0",
|
||||
"ts-node": "^3.3.0"
|
||||
}
|
||||
}
|
||||
7
integration/hello-world/src/app.module.ts
Normal file
7
integration/hello-world/src/app.module.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { HelloModule } from './hello/hello.module';
|
||||
|
||||
@Module({
|
||||
imports: [HelloModule],
|
||||
})
|
||||
export class ApplicationModule {}
|
||||
10
integration/hello-world/src/hello/dto/test.dto.ts
Normal file
10
integration/hello-world/src/hello/dto/test.dto.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { IsString, IsNotEmpty, IsNumber } from 'class-validator';
|
||||
|
||||
export class TestDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
string: string;
|
||||
|
||||
@IsNumber()
|
||||
number: number;
|
||||
}
|
||||
24
integration/hello-world/src/hello/hello.controller.ts
Normal file
24
integration/hello-world/src/hello/hello.controller.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { HelloService } from './hello.service';
|
||||
import { Controller, Get, Post, Body } from '@nestjs/common';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { of } from 'rxjs/observable/of';
|
||||
|
||||
@Controller('hello')
|
||||
export class HelloController {
|
||||
constructor(private readonly helloService: HelloService) {}
|
||||
|
||||
@Get()
|
||||
greeting(): string {
|
||||
return this.helloService.greeting();
|
||||
}
|
||||
|
||||
@Get('async')
|
||||
async asyncGreeting(): Promise<string> {
|
||||
return await this.helloService.greeting();
|
||||
}
|
||||
|
||||
@Get('stream')
|
||||
streamGreeting(): Observable<string> {
|
||||
return of(this.helloService.greeting());
|
||||
}
|
||||
}
|
||||
9
integration/hello-world/src/hello/hello.module.ts
Normal file
9
integration/hello-world/src/hello/hello.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { HelloController } from './hello.controller';
|
||||
import { HelloService } from './hello.service';
|
||||
|
||||
@Module({
|
||||
controllers: [HelloController],
|
||||
providers: [HelloService],
|
||||
})
|
||||
export class HelloModule {}
|
||||
8
integration/hello-world/src/hello/hello.service.ts
Normal file
8
integration/hello-world/src/hello/hello.service.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class HelloService {
|
||||
greeting(): string {
|
||||
return 'Hello world!';
|
||||
}
|
||||
}
|
||||
22
integration/hello-world/tsconfig.json
Normal file
22
integration/hello-world/tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"removeComments": true,
|
||||
"noLib": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es6",
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"e2e/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
53
integration/hello-world/tslint.json
Normal file
53
integration/hello-world/tslint.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {
|
||||
"no-unused-expression": true
|
||||
},
|
||||
"rules": {
|
||||
"eofline": false,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"ordered-imports": [
|
||||
false
|
||||
],
|
||||
"max-line-length": [
|
||||
150
|
||||
],
|
||||
"member-ordering": [
|
||||
false
|
||||
],
|
||||
"curly": false,
|
||||
"interface-name": [
|
||||
false
|
||||
],
|
||||
"array-type": [
|
||||
false
|
||||
],
|
||||
"member-access": [
|
||||
false
|
||||
],
|
||||
"no-empty-interface": false,
|
||||
"no-empty": false,
|
||||
"arrow-parens": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"no-unused-expression": false,
|
||||
"max-classes-per-file": [
|
||||
false
|
||||
],
|
||||
"variable-name": [
|
||||
false
|
||||
],
|
||||
"one-line": [
|
||||
false
|
||||
],
|
||||
"one-variable-per-declaration": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
||||
21
integration/injector/.gitignore
vendored
Normal file
21
integration/injector/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDE
|
||||
/.idea
|
||||
/.awcache
|
||||
/.vscode
|
||||
|
||||
# misc
|
||||
npm-debug.log
|
||||
|
||||
# example
|
||||
/quick-start
|
||||
|
||||
# tests
|
||||
/test
|
||||
/coverage
|
||||
/.nyc_output
|
||||
|
||||
# dist
|
||||
/dist
|
||||
37
integration/injector/e2e/injector.spec.ts
Normal file
37
integration/injector/e2e/injector.spec.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { expect } from 'chai';
|
||||
import { Test, TestingModuleBuilder } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { ExportsModule } from '../src/exports/exports.module';
|
||||
import { TestingModule } from '@nestjs/testing/testing-module';
|
||||
import { UnknownExportException } from '@nestjs/core/errors/exceptions/unknown-export.exception';
|
||||
import { UndefinedDependencyException } from '@nestjs/core/errors/exceptions/undefined-dependency.exception';
|
||||
import { InjectModule } from '../src/inject/inject.module';
|
||||
import { RuntimeException } from '@nestjs/core/errors/exceptions/runtime.exception';
|
||||
|
||||
describe('Injector', () => {
|
||||
describe('when "providers" and "exports" properties are inconsistent', () => {
|
||||
it(`should fail with "UnknownExportException"`, async () => {
|
||||
try {
|
||||
const builder = Test.createTestingModule({
|
||||
imports: [ExportsModule],
|
||||
});
|
||||
await builder.compile();
|
||||
} catch (err) {
|
||||
expect(err).to.be.instanceof(UnknownExportException);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('when Nest cannot resolve dependencies', () => {
|
||||
it(`should fail with "RuntimeException"`, async () => {
|
||||
try {
|
||||
const builder = Test.createTestingModule({
|
||||
imports: [InjectModule],
|
||||
});
|
||||
await builder.compile();
|
||||
} catch (err) {
|
||||
expect(err).to.be.instanceof(RuntimeException);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
27
integration/injector/package.json
Normal file
27
integration/injector/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "nest-typescript-starter",
|
||||
"version": "1.0.0",
|
||||
"description": "Nest TypeScript starter repository",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "ts-node src/main"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^4.3.0",
|
||||
"@nestjs/core": "^4.3.0",
|
||||
"@nestjs/microservices": "^4.3.0",
|
||||
"@nestjs/testing": "^4.3.0",
|
||||
"@nestjs/websockets": "^4.3.0",
|
||||
"class-transformer": "^0.1.7",
|
||||
"class-validator": "^0.7.2",
|
||||
"redis": "^2.7.1",
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"rxjs": "^5.4.3",
|
||||
"typescript": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^7.0.41",
|
||||
"supertest": "^3.0.0",
|
||||
"ts-node": "^3.3.0"
|
||||
}
|
||||
}
|
||||
7
integration/injector/src/app.module.ts
Normal file
7
integration/injector/src/app.module.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ExportsModule } from './exports/exports.module';
|
||||
|
||||
@Module({
|
||||
imports: [ExportsModule],
|
||||
})
|
||||
export class ApplicationModule {}
|
||||
7
integration/injector/src/exports/exports.module.ts
Normal file
7
integration/injector/src/exports/exports.module.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ExportsService } from './exports.service';
|
||||
|
||||
@Module({
|
||||
exports: [ExportsService],
|
||||
})
|
||||
export class ExportsModule {}
|
||||
4
integration/injector/src/exports/exports.service.ts
Normal file
4
integration/injector/src/exports/exports.service.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class ExportsService {}
|
||||
4
integration/injector/src/inject/core.service.ts
Normal file
4
integration/injector/src/inject/core.service.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class CoreService {}
|
||||
7
integration/injector/src/inject/inject.module.ts
Normal file
7
integration/injector/src/inject/inject.module.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { InjectService } from './inject.service';
|
||||
|
||||
@Module({
|
||||
providers: [InjectService],
|
||||
})
|
||||
export class InjectModule {}
|
||||
7
integration/injector/src/inject/inject.service.ts
Normal file
7
integration/injector/src/inject/inject.service.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CoreService } from './core.service';
|
||||
|
||||
@Injectable()
|
||||
export class InjectService {
|
||||
constructor(private readonly coreService: CoreService) {}
|
||||
}
|
||||
22
integration/injector/tsconfig.json
Normal file
22
integration/injector/tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"removeComments": true,
|
||||
"noLib": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es6",
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"e2e/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
53
integration/injector/tslint.json
Normal file
53
integration/injector/tslint.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {
|
||||
"no-unused-expression": true
|
||||
},
|
||||
"rules": {
|
||||
"eofline": false,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"ordered-imports": [
|
||||
false
|
||||
],
|
||||
"max-line-length": [
|
||||
150
|
||||
],
|
||||
"member-ordering": [
|
||||
false
|
||||
],
|
||||
"curly": false,
|
||||
"interface-name": [
|
||||
false
|
||||
],
|
||||
"array-type": [
|
||||
false
|
||||
],
|
||||
"member-access": [
|
||||
false
|
||||
],
|
||||
"no-empty-interface": false,
|
||||
"no-empty": false,
|
||||
"arrow-parens": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"no-unused-expression": false,
|
||||
"max-classes-per-file": [
|
||||
false
|
||||
],
|
||||
"variable-name": [
|
||||
false
|
||||
],
|
||||
"one-line": [
|
||||
false
|
||||
],
|
||||
"one-variable-per-declaration": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
||||
21
integration/microservices/.gitignore
vendored
Normal file
21
integration/microservices/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDE
|
||||
/.idea
|
||||
/.awcache
|
||||
/.vscode
|
||||
|
||||
# misc
|
||||
npm-debug.log
|
||||
|
||||
# example
|
||||
/quick-start
|
||||
|
||||
# tests
|
||||
/test
|
||||
/coverage
|
||||
/.nyc_output
|
||||
|
||||
# dist
|
||||
/dist
|
||||
39
integration/microservices/e2e/multicast-nats.spec.ts
Normal file
39
integration/microservices/e2e/multicast-nats.spec.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import * as express from 'express';
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Transport } from '@nestjs/microservices';
|
||||
import { NatsMulticastController } from '../src/nats/nats-multicast.controller';
|
||||
|
||||
describe('NATS transport', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
controllers: [NatsMulticastController],
|
||||
}).compile();
|
||||
|
||||
server = express();
|
||||
app = module.createNestApplication(server);
|
||||
app.connectMicroservice({
|
||||
transport: Transport.NATS,
|
||||
url: 'nats://localhost:4222'
|
||||
});
|
||||
app.connectMicroservice({
|
||||
transport: Transport.NATS,
|
||||
});
|
||||
await app.startAllMicroservicesAsync();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`Multicast (2 subscribers)`, () => {
|
||||
return request(server)
|
||||
.get('/multicast')
|
||||
.expect(200, '2');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
39
integration/microservices/e2e/multicast-redis.spec.ts
Normal file
39
integration/microservices/e2e/multicast-redis.spec.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import * as express from 'express';
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Transport } from '@nestjs/microservices';
|
||||
import { RedisController } from '../src/redis/redis.controller';
|
||||
import { RedisMulticastController } from '../src/redis/redis-multicast.controller';
|
||||
|
||||
describe('REDIS transport', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
controllers: [RedisMulticastController],
|
||||
}).compile();
|
||||
|
||||
server = express();
|
||||
app = module.createNestApplication(server);
|
||||
app.connectMicroservice({
|
||||
transport: Transport.REDIS,
|
||||
});
|
||||
app.connectMicroservice({
|
||||
transport: Transport.REDIS,
|
||||
});
|
||||
await app.startAllMicroservicesAsync();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`Multicast (2 subscribers)`, () => {
|
||||
return request(server)
|
||||
.get('/multicast')
|
||||
.expect(200, '2');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
59
integration/microservices/e2e/sum-nats.spec.ts
Normal file
59
integration/microservices/e2e/sum-nats.spec.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import * as express from 'express';
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Transport } from '@nestjs/microservices';
|
||||
import { NatsController } from '../src/nats/nats.controller';
|
||||
|
||||
describe('NATS transport', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
controllers: [NatsController],
|
||||
}).compile();
|
||||
|
||||
server = express();
|
||||
app = module.createNestApplication(server);
|
||||
app.connectMicroservice({
|
||||
transport: Transport.NATS,
|
||||
url: 'nats://localhost:4222'
|
||||
});
|
||||
await app.startAllMicroservicesAsync();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`/POST`, () => {
|
||||
return request(server)
|
||||
.post('/?command=sum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (Promise/async)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=asyncSum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200)
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (Observable stream)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=streamSum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (streaming)`, () => {
|
||||
return request(server)
|
||||
.post('/stream')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
71
integration/microservices/e2e/sum-redis.spec.ts
Normal file
71
integration/microservices/e2e/sum-redis.spec.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import * as express from 'express';
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Transport } from '@nestjs/microservices';
|
||||
import { RedisController } from '../src/redis/redis.controller';
|
||||
|
||||
describe('REDIS transport', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
controllers: [RedisController],
|
||||
}).compile();
|
||||
|
||||
server = express();
|
||||
app = module.createNestApplication(server);
|
||||
app.connectMicroservice({
|
||||
transport: Transport.REDIS,
|
||||
});
|
||||
await app.startAllMicroservicesAsync();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`/POST`, () => {
|
||||
return request(server)
|
||||
.post('/?command=sum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (Promise/async)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=asyncSum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200)
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (Observable stream)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=streamSum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (concurrent)`, () => {
|
||||
return request(server)
|
||||
.post('/concurrent')
|
||||
.send([
|
||||
[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],
|
||||
])
|
||||
.expect(200, 'true');
|
||||
});
|
||||
|
||||
it(`/POST (streaming)`, () => {
|
||||
return request(server)
|
||||
.post('/stream')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
77
integration/microservices/e2e/sum-rpc.spec.ts
Normal file
77
integration/microservices/e2e/sum-rpc.spec.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import * as express from 'express';
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { ApplicationModule } from './../src/app.module';
|
||||
import { Transport } from '@nestjs/microservices';
|
||||
|
||||
describe('RPC transport', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
imports: [ApplicationModule],
|
||||
}).compile();
|
||||
|
||||
server = express();
|
||||
app = module.createNestApplication(server);
|
||||
app.connectMicroservice({
|
||||
transport: Transport.TCP,
|
||||
});
|
||||
await app.startAllMicroservicesAsync();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`/POST`, () => {
|
||||
return request(server)
|
||||
.post('/?command=sum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (Promise/async)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=asyncSum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200)
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (Observable stream)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=streamSum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (concurrent)`, () => {
|
||||
return request(server)
|
||||
.post('/concurrent')
|
||||
.send([
|
||||
[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],
|
||||
])
|
||||
.expect(200, 'true');
|
||||
});
|
||||
|
||||
it(`/POST (streaming)`, () => {
|
||||
return request(server)
|
||||
.post('/stream')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (pattern not found)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=test')
|
||||
.expect(500);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
59
integration/microservices/e2e/sum-stan.spec.ts
Normal file
59
integration/microservices/e2e/sum-stan.spec.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/*import * as express from 'express';
|
||||
import * as request from 'supertest';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Transport } from '@nestjs/microservices';
|
||||
import { NatsController } from '../src/nats/nats.controller';
|
||||
|
||||
describe('STAN transport', () => {
|
||||
let server;
|
||||
let app: INestApplication;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
controllers: [NatsController],
|
||||
}).compile();
|
||||
|
||||
server = express();
|
||||
app = module.createNestApplication(server);
|
||||
app.connectMicroservice({
|
||||
transport: Transport.STAN,
|
||||
});
|
||||
await app.startAllMicroservicesAsync();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it(`/POST`, () => {
|
||||
return request(server)
|
||||
.post('/?command=sum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (Promise/async)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=asyncSum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200)
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (Observable stream)`, () => {
|
||||
return request(server)
|
||||
.post('/?command=streamSum')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
it(`/POST (streaming)`, () => {
|
||||
return request(server)
|
||||
.post('/stream')
|
||||
.send([1, 2, 3, 4, 5])
|
||||
.expect(200, '15');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
*/
|
||||
27
integration/microservices/package.json
Normal file
27
integration/microservices/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "nest-typescript-starter",
|
||||
"version": "1.0.0",
|
||||
"description": "Nest TypeScript starter repository",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "ts-node src/main"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^4.3.0",
|
||||
"@nestjs/core": "^4.3.0",
|
||||
"@nestjs/microservices": "^4.3.0",
|
||||
"@nestjs/testing": "^4.3.0",
|
||||
"@nestjs/websockets": "^4.3.0",
|
||||
"class-transformer": "^0.1.7",
|
||||
"class-validator": "^0.7.2",
|
||||
"redis": "^2.7.1",
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"rxjs": "^5.4.3",
|
||||
"typescript": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^7.0.41",
|
||||
"supertest": "^3.0.0",
|
||||
"ts-node": "^3.3.0"
|
||||
}
|
||||
}
|
||||
68
integration/microservices/src/app.controller.ts
Normal file
68
integration/microservices/src/app.controller.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Controller, Get, Post, Body, Query, HttpCode } from '@nestjs/common';
|
||||
import {
|
||||
Client,
|
||||
MessagePattern,
|
||||
ClientProxy,
|
||||
Transport,
|
||||
} from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { of } from 'rxjs/observable/of';
|
||||
import { from } from 'rxjs/observable/from';
|
||||
import { scan } from 'rxjs/operators';
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
@Client({ transport: Transport.TCP })
|
||||
client: ClientProxy;
|
||||
|
||||
@Post()
|
||||
@HttpCode(200)
|
||||
call(@Query('command') cmd, @Body() data: number[]): Observable<number> {
|
||||
return this.client.send<number>({ cmd }, data);
|
||||
}
|
||||
|
||||
@Post('stream')
|
||||
@HttpCode(200)
|
||||
stream(@Body() data: number[]): Observable<number> {
|
||||
return this.client.send<number>({ cmd: 'streaming' }, data)
|
||||
.pipe(
|
||||
scan((a, b) => a + b),
|
||||
);
|
||||
}
|
||||
|
||||
@Post('concurrent')
|
||||
@HttpCode(200)
|
||||
concurrent(@Body() data: number[][]): Promise<boolean> {
|
||||
const send = async (tab: number[]) => {
|
||||
const expected = tab.reduce((a, b) => a + b);
|
||||
const result = await this.client
|
||||
.send<number>({ cmd: 'sum' }, tab)
|
||||
.toPromise();
|
||||
|
||||
return result === expected;
|
||||
};
|
||||
return data
|
||||
.map(async tab => await send(tab))
|
||||
.reduce(async (a, b) => (await a) && (await b));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'sum' })
|
||||
sum(data: number[]): number {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'asyncSum' })
|
||||
async asyncSum(data: number[]): Promise<number> {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'streamSum' })
|
||||
streamSum(data: number[]): Observable<number> {
|
||||
return of((data || []).reduce((a, b) => a + b));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'streaming' })
|
||||
streaming(data: number[]): Observable<number> {
|
||||
return from(data);
|
||||
}
|
||||
}
|
||||
7
integration/microservices/src/app.module.ts
Normal file
7
integration/microservices/src/app.module.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [AppController],
|
||||
})
|
||||
export class ApplicationModule {}
|
||||
8
integration/microservices/src/main.ts
Normal file
8
integration/microservices/src/main.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { ApplicationModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(ApplicationModule);
|
||||
await app.listen(3000);
|
||||
}
|
||||
bootstrap();
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import {
|
||||
Client,
|
||||
MessagePattern,
|
||||
ClientProxy,
|
||||
Transport,
|
||||
} from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { scan, take } from 'rxjs/operators';
|
||||
|
||||
@Controller()
|
||||
export class NatsMulticastController {
|
||||
@Client({ transport: Transport.NATS, url: 'nats://localhost:4222' })
|
||||
client: ClientProxy;
|
||||
|
||||
@Get('multicast')
|
||||
multicats() {
|
||||
return this.client
|
||||
.send<number>({ cmd: 'multicast' }, {})
|
||||
.pipe(scan((a, b) => a + b), take(2));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'multicast' })
|
||||
replyMulticast(): Observable<number> {
|
||||
return new Observable(observer => observer.next(1));
|
||||
}
|
||||
}
|
||||
67
integration/microservices/src/nats/nats.controller.ts
Normal file
67
integration/microservices/src/nats/nats.controller.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { Controller, Get, Post, Body, Query, HttpCode } from '@nestjs/common';
|
||||
import {
|
||||
Client,
|
||||
MessagePattern,
|
||||
ClientProxy,
|
||||
Transport,
|
||||
} from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { of } from 'rxjs/observable/of';
|
||||
import { from } from 'rxjs/observable/from';
|
||||
import { scan } from 'rxjs/operators';
|
||||
|
||||
@Controller()
|
||||
export class NatsController {
|
||||
@Client({ transport: Transport.NATS, url: 'nats://localhost:4222' })
|
||||
client: ClientProxy;
|
||||
|
||||
@Post()
|
||||
@HttpCode(200)
|
||||
call(@Query('command') cmd, @Body() data: number[]): Observable<number> {
|
||||
return this.client.send<number>({ cmd }, data);
|
||||
}
|
||||
|
||||
@Post('stream')
|
||||
@HttpCode(200)
|
||||
stream(@Body() data: number[]): Observable<number> {
|
||||
return this.client
|
||||
.send<number>({ cmd: 'streaming' }, data)
|
||||
.pipe(scan((a, b) => a + b));
|
||||
}
|
||||
|
||||
@Post('concurrent')
|
||||
@HttpCode(200)
|
||||
concurrent(@Body() data: number[][]): Promise<boolean> {
|
||||
const send = async (tab: number[]) => {
|
||||
const expected = tab.reduce((a, b) => a + b);
|
||||
const result = await this.client
|
||||
.send<number>({ cmd: 'sum' }, tab)
|
||||
.toPromise();
|
||||
|
||||
return result === expected;
|
||||
};
|
||||
return data
|
||||
.map(async tab => await send(tab))
|
||||
.reduce(async (a, b) => (await a) && (await b));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'sum' })
|
||||
sum(data: number[]): number {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'asyncSum' })
|
||||
async asyncSum(data: number[]): Promise<number> {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'streamSum' })
|
||||
streamSum(data: number[]): Observable<number> {
|
||||
return of((data || []).reduce((a, b) => a + b));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'streaming' })
|
||||
streaming(data: number[]): Observable<number> {
|
||||
return from(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import {
|
||||
Client,
|
||||
MessagePattern,
|
||||
ClientProxy,
|
||||
Transport,
|
||||
} from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { scan, take } from 'rxjs/operators';
|
||||
|
||||
@Controller()
|
||||
export class RedisMulticastController {
|
||||
@Client({ transport: Transport.REDIS })
|
||||
client: ClientProxy;
|
||||
|
||||
@Get('multicast')
|
||||
multicats() {
|
||||
return this.client.send<number>({ cmd: 'multicast' }, {})
|
||||
.pipe(
|
||||
scan((a, b) => a + b),
|
||||
take(2),
|
||||
);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'multicast' })
|
||||
replyMulticast(): Observable<number> {
|
||||
return new Observable((observer) => observer.next(1));
|
||||
}
|
||||
}
|
||||
68
integration/microservices/src/redis/redis.controller.ts
Normal file
68
integration/microservices/src/redis/redis.controller.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Controller, Get, Post, Body, Query, HttpCode } from '@nestjs/common';
|
||||
import {
|
||||
Client,
|
||||
MessagePattern,
|
||||
ClientProxy,
|
||||
Transport,
|
||||
} from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { of } from 'rxjs/observable/of';
|
||||
import { from } from 'rxjs/observable/from';
|
||||
import { scan } from 'rxjs/operators';
|
||||
|
||||
@Controller()
|
||||
export class RedisController {
|
||||
@Client({ transport: Transport.REDIS })
|
||||
client: ClientProxy;
|
||||
|
||||
@Post()
|
||||
@HttpCode(200)
|
||||
call(@Query('command') cmd, @Body() data: number[]): Observable<number> {
|
||||
return this.client.send<number>({ cmd }, data);
|
||||
}
|
||||
|
||||
@Post('stream')
|
||||
@HttpCode(200)
|
||||
stream(@Body() data: number[]): Observable<number> {
|
||||
return this.client.send<number>({ cmd: 'streaming' }, data)
|
||||
.pipe(
|
||||
scan((a, b) => a + b),
|
||||
);
|
||||
}
|
||||
|
||||
@Post('concurrent')
|
||||
@HttpCode(200)
|
||||
concurrent(@Body() data: number[][]): Promise<boolean> {
|
||||
const send = async (tab: number[]) => {
|
||||
const expected = tab.reduce((a, b) => a + b);
|
||||
const result = await this.client
|
||||
.send<number>({ cmd: 'sum' }, tab)
|
||||
.toPromise();
|
||||
|
||||
return result === expected;
|
||||
};
|
||||
return data
|
||||
.map(async tab => await send(tab))
|
||||
.reduce(async (a, b) => (await a) && (await b));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'sum' })
|
||||
sum(data: number[]): number {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'asyncSum' })
|
||||
async asyncSum(data: number[]): Promise<number> {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'streamSum' })
|
||||
streamSum(data: number[]): Observable<number> {
|
||||
return of((data || []).reduce((a, b) => a + b));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'streaming' })
|
||||
streaming(data: number[]): Observable<number> {
|
||||
return from(data);
|
||||
}
|
||||
}
|
||||
68
integration/microservices/src/stan/stan.controller.ts
Normal file
68
integration/microservices/src/stan/stan.controller.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Controller, Get, Post, Body, Query, HttpCode } from '@nestjs/common';
|
||||
import {
|
||||
Client,
|
||||
MessagePattern,
|
||||
ClientProxy,
|
||||
Transport,
|
||||
} from '@nestjs/microservices';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { of } from 'rxjs/observable/of';
|
||||
import { from } from 'rxjs/observable/from';
|
||||
import { scan } from 'rxjs/operators';
|
||||
|
||||
@Controller()
|
||||
export class NatsController {
|
||||
@Client({ transport: Transport.STAN })
|
||||
client: ClientProxy;
|
||||
|
||||
@Post()
|
||||
@HttpCode(200)
|
||||
call(@Query('command') cmd, @Body() data: number[]): Observable<number> {
|
||||
return this.client.send<number>({ cmd }, data);
|
||||
}
|
||||
|
||||
@Post('stream')
|
||||
@HttpCode(200)
|
||||
stream(@Body() data: number[]): Observable<number> {
|
||||
return this.client.send<number>({ cmd: 'streaming' }, data)
|
||||
.pipe(
|
||||
scan((a, b) => a + b),
|
||||
);
|
||||
}
|
||||
|
||||
@Post('concurrent')
|
||||
@HttpCode(200)
|
||||
concurrent(@Body() data: number[][]): Promise<boolean> {
|
||||
const send = async (tab: number[]) => {
|
||||
const expected = tab.reduce((a, b) => a + b);
|
||||
const result = await this.client
|
||||
.send<number>({ cmd: 'sum' }, tab)
|
||||
.toPromise();
|
||||
|
||||
return result === expected;
|
||||
};
|
||||
return data
|
||||
.map(async tab => await send(tab))
|
||||
.reduce(async (a, b) => (await a) && (await b));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'sum' })
|
||||
sum(data: number[]): number {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'asyncSum' })
|
||||
async asyncSum(data: number[]): Promise<number> {
|
||||
return (data || []).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'streamSum' })
|
||||
streamSum(data: number[]): Observable<number> {
|
||||
return of((data || []).reduce((a, b) => a + b));
|
||||
}
|
||||
|
||||
@MessagePattern({ cmd: 'streaming' })
|
||||
streaming(data: number[]): Observable<number> {
|
||||
return from(data);
|
||||
}
|
||||
}
|
||||
22
integration/microservices/tsconfig.json
Normal file
22
integration/microservices/tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"removeComments": true,
|
||||
"noLib": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es6",
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"e2e/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
53
integration/microservices/tslint.json
Normal file
53
integration/microservices/tslint.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {
|
||||
"no-unused-expression": true
|
||||
},
|
||||
"rules": {
|
||||
"eofline": false,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"ordered-imports": [
|
||||
false
|
||||
],
|
||||
"max-line-length": [
|
||||
150
|
||||
],
|
||||
"member-ordering": [
|
||||
false
|
||||
],
|
||||
"curly": false,
|
||||
"interface-name": [
|
||||
false
|
||||
],
|
||||
"array-type": [
|
||||
false
|
||||
],
|
||||
"member-access": [
|
||||
false
|
||||
],
|
||||
"no-empty-interface": false,
|
||||
"no-empty": false,
|
||||
"arrow-parens": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"no-unused-expression": false,
|
||||
"max-classes-per-file": [
|
||||
false
|
||||
],
|
||||
"variable-name": [
|
||||
false
|
||||
],
|
||||
"one-line": [
|
||||
false
|
||||
],
|
||||
"one-variable-per-declaration": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
||||
Reference in New Issue
Block a user