Skip to content

Commit

Permalink
feature(@nestjs/microservices) grpc improvements (add root), cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilmysliwiec committed May 25, 2018
1 parent ae128f6 commit 17a609c
Show file tree
Hide file tree
Showing 31 changed files with 173 additions and 288 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Assigns the metadata to the class / function under specified `key`.
* Assigns the metadata to the class/function under specified `key`.
* This metadata can be reflected using `Reflector` class.
*/
export const ReflectMetadata = (metadataKey, metadataValue) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ export interface ValidatorOptions {
*/
value?: boolean;
};
/**
* Settings true will cause fail validation of unknown objects.
*/
forbidUnknownValues?: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Transport } from '../../enums/transport.enum';
import { CustomTransportStrategy } from './custom-transport-strategy.interface';
import { MqttClientOptions } from '../external/mqtt-options.interface';
import { CustomTransportStrategy } from './custom-transport-strategy.interface';

export type MicroserviceOptions =
| GrpcOptions
Expand All @@ -21,6 +21,7 @@ export interface GrpcOptions {
url?: string;
credentials?: any;
protoPath: string;
root?: string;
package: string;
};
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/errors/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const InvalidModuleMessage = (scope: string) =>
`Nest cannot create the module instance. The frequent reason of this exception is the circular dependency between modules. Use forwardRef() to avoid it (read more https://docs.nestjs.com/advanced/circular-dependency). Scope [${scope}]`;

export const UnknownExportMessage = (module: string) =>
`Nest cannot export component / module that is not a part of the currently proccessed module (${module}). Please verify whether each exported unit is available in this particular context.`;
`Nest cannot export component/module that is not a part of the currently proccessed module (${module}). Please verify whether each exported unit is available in this particular context.`;

export const INVALID_MIDDLEWARE_CONFIGURATION = `Invalid middleware configuration passed inside the module 'configure()' method.`;
export const UNKNOWN_REQUEST_MAPPING = `Request mapping properties not defined in the @RequestMapping() annotation!`;
Expand Down
10 changes: 4 additions & 6 deletions packages/core/exceptions/exceptions-handler.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { messages } from '../constants';
import { Logger, HttpServer } from '@nestjs/common';
import { HttpException, HttpServer, Logger } from '@nestjs/common';
import { ExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions/exception-filter-metadata.interface';
import { ArgumentsHost } from '@nestjs/common/interfaces/features/arguments-host.interface';
import { isEmpty, isObject } from '@nestjs/common/utils/shared.utils';
import { messages } from '../constants';
import { InvalidExceptionFilterException } from '../errors/exceptions/invalid-exception-filter.exception';
import { HttpException } from '@nestjs/common';
import { ArgumentsHost } from '@nestjs/common/interfaces/features/arguments-host.interface';

export class ExceptionsHandler {
private static readonly logger = new Logger(ExceptionsHandler.name);
Expand All @@ -20,8 +19,7 @@ export class ExceptionsHandler {
statusCode: 500,
message: messages.UNKNOWN_EXCEPTION_MESSAGE,
};
const statusCode = 500;
this.applicationRef.reply(ctx.getArgByIndex(1), body, statusCode);
this.applicationRef.reply(ctx.getArgByIndex(1), body, body.statusCode);
if (this.isExceptionObject(exception)) {
return ExceptionsHandler.logger.error(
exception.message,
Expand Down
29 changes: 9 additions & 20 deletions packages/core/injector/module.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
import { InstanceWrapper, NestContainer } from './container';
import {
Injectable,
Controller,
NestModule,
DynamicModule,
} from '@nestjs/common/interfaces';
import { UnknownExportException } from '../errors/exceptions/unknown-export.exception';
import { Controller, DynamicModule, Injectable, NestModule } from '@nestjs/common/interfaces';
import { Type } from '@nestjs/common/interfaces/type.interface';
import { ModuleRef } from './module-ref';
import {
isFunction,
isNil,
isUndefined,
isString,
isSymbol,
} from '@nestjs/common/utils/shared.utils';
import { isFunction, isNil, isString, isSymbol, isUndefined } from '@nestjs/common/utils/shared.utils';
import { RuntimeException } from '../errors/exceptions/runtime.exception';
import { ExternalContextCreator } from './../helpers/external-context-creator';
import { UnknownExportException } from '../errors/exceptions/unknown-export.exception';
import { Reflector } from '../services/reflector.service';
import { GuardsConsumer } from './../guards/guards-consumer';
import { GuardsContextCreator } from './../guards/guards-context-creator';
import { InterceptorsContextCreator } from './../interceptors/interceptors-context-creator';
import { ExternalContextCreator } from './../helpers/external-context-creator';
import { InterceptorsConsumer } from './../interceptors/interceptors-consumer';
import { GuardsConsumer } from './../guards/guards-consumer';
import { InterceptorsContextCreator } from './../interceptors/interceptors-context-creator';
import { InstanceWrapper, NestContainer } from './container';
import { ModuleRef } from './module-ref';
import { ModulesContainer } from './modules-container';
import { Reflector } from '../services/reflector.service';
import { HTTP_SERVER_REF } from './tokens';

export interface CustomComponent {
Expand Down
35 changes: 19 additions & 16 deletions packages/core/middleware/middleware-module.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
import { NestContainer } from '../injector/container';
import { MiddlewareBuilder } from './builder';
import { MiddlewareContainer, MiddlewareWrapper } from './container';
import { MiddlewareResolver } from './resolver';
import { ControllerMetadata } from '@nestjs/common/interfaces/controllers/controller-metadata.interface';
import { NestModule } from '@nestjs/common/interfaces/modules/nest-module.interface';
import { MiddlewareConfiguration } from '@nestjs/common/interfaces/middleware/middleware-configuration.interface';
import { InvalidMiddlewareException } from '../errors/exceptions/invalid-middleware.exception';
import { RequestMethod } from '@nestjs/common/enums/request-method.enum';
import { RoutesMapper } from './routes-mapper';
import { RouterProxy } from '../router/router-proxy';
import { ExceptionsHandler } from '../exceptions/exceptions-handler';
import { Module } from '../injector/module';
import { RouterMethodFactory } from '../helpers/router-method-factory';
import { MiddlewareConfiguration } from '@nestjs/common/interfaces/middleware/middleware-configuration.interface';
import { NestMiddleware } from '@nestjs/common/interfaces/middleware/nest-middleware.interface';
import { NestModule } from '@nestjs/common/interfaces/modules/nest-module.interface';
import { Type } from '@nestjs/common/interfaces/type.interface';
import { RuntimeException } from '../errors/exceptions/runtime.exception';
import { isUndefined } from '@nestjs/common/utils/shared.utils';
import { isUndefined, validatePath } from '@nestjs/common/utils/shared.utils';
import { ApplicationConfig } from '../application-config';
import { InvalidMiddlewareException } from '../errors/exceptions/invalid-middleware.exception';
import { RuntimeException } from '../errors/exceptions/runtime.exception';
import { ExceptionsHandler } from '../exceptions/exceptions-handler';
import { RouterMethodFactory } from '../helpers/router-method-factory';
import { NestContainer } from '../injector/container';
import { Module } from '../injector/module';
import { RouterExceptionFilters } from '../router/router-exception-filters';
import { RouterProxy } from '../router/router-proxy';
import { MiddlewareBuilder } from './builder';
import { MiddlewareContainer, MiddlewareWrapper } from './container';
import { MiddlewareResolver } from './resolver';
import { RoutesMapper } from './routes-mapper';

export class MiddlewareModule {
private readonly routerProxy = new RouterProxy();
private readonly routerMethodFactory = new RouterMethodFactory();
private routerExceptionFilter: RouterExceptionFilters;
private routesMapper: RoutesMapper;
private resolver: MiddlewareResolver;
private config: ApplicationConfig;

public async register(
middlewareContainer: MiddlewareContainer,
Expand All @@ -39,6 +39,7 @@ export class MiddlewareModule {
);
this.routesMapper = new RoutesMapper(container);
this.resolver = new MiddlewareResolver(middlewareContainer);
this.config = config;

const modules = container.getModules();
await this.resolveMiddleware(middlewareContainer, modules);
Expand Down Expand Up @@ -184,6 +185,8 @@ export class MiddlewareModule {
path: string,
) {
const proxy = this.routerProxy.createProxy(middleware, exceptionsHandler);
router(path, proxy);
const prefix = this.config.getGlobalPrefix();
const basePath = prefix ? validatePath(prefix) : '';
router(basePath + path, proxy);
}
}
48 changes: 22 additions & 26 deletions packages/core/nest-application.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,46 @@
import * as cors from 'cors';
import * as http from 'http';
import * as https from 'https';
import * as optional from 'optional';
import * as bodyParser from 'body-parser';
import iterate from 'iterare';
import {
CanActivate,
ExceptionFilter,
INestApplication,
INestMicroservice,
NestInterceptor,
OnModuleDestroy,
PipeTransform,
WebSocketAdapter,
} from '@nestjs/common';
import {
INestApplication,
INestMicroservice,
OnModuleInit,
} from '@nestjs/common';
import { HttpServer } from '@nestjs/common/interfaces';
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
import { ServeStaticOptions } from '@nestjs/common/interfaces/external/serve-static-options.interface';
import { MicroserviceOptions } from '@nestjs/common/interfaces/microservices/microservice-configuration.interface';
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
import { INestExpressApplication } from '@nestjs/common/interfaces/nest-express-application.interface';
import { INestFastifyApplication } from '@nestjs/common/interfaces/nest-fastify-application.interface';
import { Logger } from '@nestjs/common/services/logger.service';
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import {
isFunction,
isNil,
isObject,
isUndefined,
validatePath,
isFunction,
isObject,
} from '@nestjs/common/utils/shared.utils';
import { MicroserviceOptions } from '@nestjs/common/interfaces/microservices/microservice-configuration.interface';
import * as bodyParser from 'body-parser';
import * as cors from 'cors';
import * as http from 'http';
import * as https from 'https';
import iterate from 'iterare';
import * as optional from 'optional';
import { ExpressAdapter } from './adapters/express-adapter';
import { FastifyAdapter } from './adapters/fastify-adapter';
import { ApplicationConfig } from './application-config';
import { messages } from './constants';
import { NestContainer } from './injector/container';
import { Module } from './injector/module';
import { MiddlewareContainer } from './middleware/container';
import { MiddlewareModule } from './middleware/middleware-module';
import { NestApplicationContext } from './nest-application-context';
import { Resolver } from './router/interfaces/resolver.interface';
import { RoutesResolver } from './router/routes-resolver';
import { MiddlewareContainer } from './middleware/container';
import { NestApplicationContext } from './nest-application-context';
import { HttpsOptions } from '@nestjs/common/interfaces/external/https-options.interface';
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
import { HttpServer } from '@nestjs/common/interfaces';
import { ExpressAdapter } from './adapters/express-adapter';
import { FastifyAdapter } from './adapters/fastify-adapter';
import { INestExpressApplication } from '@nestjs/common/interfaces/nest-express-application.interface';
import { INestFastifyApplication } from '@nestjs/common/interfaces/nest-fastify-application.interface';
import { ServeStaticOptions } from '@nestjs/common/interfaces/external/serve-static-options.interface';
import { loadPackage } from '@nestjs/common/utils/load-package.util';

const { SocketModule } =
optional('@nestjs/websockets/socket-module') || ({} as any);
Expand Down
27 changes: 8 additions & 19 deletions packages/core/router/router-exception-filters.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
import 'reflect-metadata';
import iterate from 'iterare';
import { HttpServer } from '@nestjs/common';
import { EXCEPTION_FILTERS_METADATA } from '@nestjs/common/constants';
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
import { ExceptionsHandler } from '../exceptions/exceptions-handler';
import {
EXCEPTION_FILTERS_METADATA,
FILTER_CATCH_EXCEPTIONS,
} from '@nestjs/common/constants';
import {
isEmpty,
isFunction,
isUndefined,
} from '@nestjs/common/utils/shared.utils';
import { Type } from '@nestjs/common/interfaces/index';
import { ExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions/exception-filter-metadata.interface';
import { ExceptionFilter } from '@nestjs/common/interfaces/exceptions/exception-filter.interface';
import { RouterProxyCallback } from './../router/router-proxy';
import { ApplicationConfig } from './../application-config';
import { isEmpty } from '@nestjs/common/utils/shared.utils';
import 'reflect-metadata';
import { BaseExceptionFilterContext } from '../exceptions/base-exception-filter-context';
import { HttpServer } from '@nestjs/common';
import { ExceptionsHandler } from '../exceptions/exceptions-handler';
import { NestContainer } from '../injector/container';
import { ApplicationConfig } from './../application-config';
import { RouterProxyCallback } from './../router/router-proxy';

export class RouterExceptionFilters extends BaseExceptionFilterContext {
constructor(
Expand All @@ -45,7 +34,7 @@ export class RouterExceptionFilters extends BaseExceptionFilterContext {
if (isEmpty(filters)) {
return exceptionHandler;
}
exceptionHandler.setCustomFilters(filters);
exceptionHandler.setCustomFilters(filters.reverse());
return exceptionHandler;
}

Expand Down
23 changes: 12 additions & 11 deletions packages/core/test/middlewares/middlewares-module.spec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { expect } from 'chai';
import * as sinon from 'sinon';
import { NestMiddleware } from '../../../common/interfaces/middleware/nest-middleware.interface';
import { Component } from '../../../common/decorators/core/component.decorator';
import { MiddlewareBuilder } from '../../middleware/builder';
import { MiddlewareModule } from '../../middleware/middleware-module';
import { InvalidMiddlewareException } from '../../errors/exceptions/invalid-middleware.exception';
import { RequestMethod } from '../../../common/enums/request-method.enum';
import { Controller } from '../../../common/decorators/core/controller.decorator';
import { RequestMapping } from '../../../common/decorators/http/request-mapping.decorator';
import { RuntimeException } from '../../errors/exceptions/runtime.exception';
import { RoutesMapper } from '../../middleware/routes-mapper';
import { RouterExceptionFilters } from '../../router/router-exception-filters';
import { ApplicationConfig } from '../../application-config';
import { MiddlewareContainer } from '../../middleware/container';
import { RequestMethod } from '../../../common/enums/request-method.enum';
import { NestMiddleware } from '../../../common/interfaces/middleware/nest-middleware.interface';
import { ExpressAdapter } from '../../adapters/express-adapter';
import { ApplicationConfig } from '../../application-config';
import { InvalidMiddlewareException } from '../../errors/exceptions/invalid-middleware.exception';
import { RuntimeException } from '../../errors/exceptions/runtime.exception';
import { NestContainer } from '../../injector/container';
import { MiddlewareBuilder } from '../../middleware/builder';
import { MiddlewareContainer } from '../../middleware/container';
import { MiddlewareModule } from '../../middleware/middleware-module';
import { RouterExceptionFilters } from '../../router/router-exception-filters';

describe('MiddlewareModule', () => {
let middlewareModule: MiddlewareModule;
Expand All @@ -39,12 +38,14 @@ describe('MiddlewareModule', () => {
}

beforeEach(() => {
const appConfig = new ApplicationConfig();
middlewareModule = new MiddlewareModule();
(middlewareModule as any).routerExceptionFilter = new RouterExceptionFilters(
new NestContainer(),
new ApplicationConfig(),
appConfig,
new ExpressAdapter({}),
);
(middlewareModule as any).config = appConfig;
});

describe('loadConfiguration', () => {
Expand Down
21 changes: 11 additions & 10 deletions packages/microservices/client/client-grpc.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { ClientProxy } from './client-proxy';
import { Logger } from '@nestjs/common/services/logger.service';
import { ClientOptions } from '../interfaces/client-metadata.interface';
import { GrpcOptions } from './../interfaces';
import { GRPC_DEFAULT_URL } from './../constants';
import { ClientGrpc } from './../interfaces';
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import { Observable } from 'rxjs';
import { InvalidGrpcServiceException } from '../exceptions/invalid-grpc-service.exception';
import { InvalidGrpcPackageException } from '../exceptions/invalid-grpc-package.exception';
import { InvalidGrpcServiceException } from '../exceptions/invalid-grpc-service.exception';
import { InvalidProtoDefinitionException } from '../exceptions/invalid-proto-definition.exception';
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import { ClientOptions } from '../interfaces/client-metadata.interface';
import { GRPC_DEFAULT_URL } from './../constants';
import { ClientGrpc, GrpcOptions } from './../interfaces';
import { ClientProxy } from './client-proxy';

let grpcPackage: any = {};

Expand Down Expand Up @@ -102,9 +101,11 @@ export class ClientGrpcProxy extends ClientProxy implements ClientGrpc {

public loadProto(): any {
try {
const context = grpcPackage.load(
this.getOptionsProp<GrpcOptions>(this.options, 'protoPath'),
);
const root = this.getOptionsProp<GrpcOptions>(this.options, 'root');
const file = this.getOptionsProp<GrpcOptions>(this.options, 'protoPath');
const options = root ? { root, file } : file;

const context = grpcPackage.load(options);
return context;
} catch (e) {
const invalidProtoError = new InvalidProtoDefinitionException();
Expand Down
17 changes: 5 additions & 12 deletions packages/microservices/client/client-mqtt.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import { ClientProxy } from './client-proxy';
import { Logger } from '@nestjs/common/services/logger.service';
import { ClientOptions } from '../interfaces/client-metadata.interface';
import {
MQTT_DEFAULT_URL,
MESSAGE_EVENT,
ERROR_EVENT,
CONNECT_EVENT,
SUBSCRIBE,
} from './../constants';
import { WritePacket, MqttOptions } from './../interfaces';
import { ReadPacket, PacketId } from './../interfaces';
import { MqttClient } from '../external/mqtt-client.interface';
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import { MqttClient } from '../external/mqtt-client.interface';
import { ClientOptions } from '../interfaces/client-metadata.interface';
import { ERROR_EVENT, MESSAGE_EVENT, MQTT_DEFAULT_URL } from './../constants';
import { MqttOptions, PacketId, ReadPacket, WritePacket } from './../interfaces';
import { ClientProxy } from './client-proxy';
import { ECONNREFUSED } from './constants';

let mqttPackage: any = {};
Expand Down
Loading

0 comments on commit 17a609c

Please sign in to comment.