标签: nestjs

mongoose @prop() 装饰器类型:模式定义中的对象 _ NestJS

我最近搬到了 NestJs。我对定义 mongoose schema 的属性有一些疑问。

如何在模式内定义对象类型:

在express中我定义了这样的属性:

 foo:{
        type: Object
    },
Run Code Online (Sandbox Code Playgroud)

现在在这里我不能使用对象类型。我也确实使用了任何关键字。

mongoose nestjs

2
推荐指数
1
解决办法
5582
查看次数

NestJS 提供者需要无状态吗?

我是一名长期学习 NestJS 的 Spring 开发人员。这些相似之处是如此惊人,我很喜欢这让我变得高效。然而,一些文档让我对一件事感到困惑。

我尝试将 Nest“提供者”比作具有默认范围的 Spring beans。例如,我创建 @Injectable 服务类,并将它们视为类似于 Spring @Services。因此,我假设这些服务类需要是线程安全的 - 无状态等。但是,这里的 Nest 文档对我来说有点含糊,有点暗示这可能没有必要(强调我的):

对于来自不同编程语言背景的人来说,可能会意外地发现,在 Nest 中,几乎所有内容都在传入请求之间共享。我们有一个到数据库的连接池、具有全局状态的单例服务等。请记住,Node.js 不遵循请求/响应多线程无状态模型,在该模型中,每个请求都由单独的线程处理。因此,使用单例实例对于我们的应用程序来说是完全安全的。

如果单个请求不在自己的线程中处理,那么 Nest 提供程序可以包含可变状态吗?应用程序需要确保每个传入请求都以“干净的状态”开始 - 例如,使用 NestInterceptor 初始化该状态。但对我来说,该文档显示提供程序是作为单例创建的,因此可以用作类似于数据包装容器的东西,就像 Java 中的 ThreadLocal 一样。

我是否读错了,或者这是 Nest 和 Spring 之间的行为差​​异?

spring nestjs

2
推荐指数
1
解决办法
1254
查看次数

在 monorepo 中对 NestJs dockerized 应用程序进行 VS 代码调试

一段时间以来,我一直在尝试弄清楚如何设置节点调试进程的附件,这些进程在我的环境中从单一存储库设置中的多个正在运行的 Nestjs 应用程序中公开。(用VS代码)

https://github.com/bozvul993/nest-testing-mono-repo-debug

理想情况下,我希望在代码更改时重新启动调试会话[如果可能的话],但更重要的是工作。

我已经为我的示例项目提供了一个存储库。运行/docker文件夹 内的应用程序docker-compose -f dev.yml up 这将显示 monorepo 中的三个应用程序。所有向主机公开其默认节点调试端口的应用程序...

我用来尝试此操作的 vs code 启动配置包括:

            "type": "node",
            "request": "attach",
            "name": "Debug App1",
            "address": "0.0.0.0",
            "port": 9231,
            "localRoot": "${workspaceFolder}/mono-repo",
            "remoteRoot": "/app/mono-repo",
            "trace": true,
            "restart": true,
            "sourceMaps": true,
            "skipFiles": [
                "<node_internals>/**"
            ]
        }


With Web-storm this was easier to achieve somehow..
Run Code Online (Sandbox Code Playgroud)

debugging node.js visual-studio-code nestjs

2
推荐指数
1
解决办法
2970
查看次数

为什么 jwtService 未定义?

JwtAuthGuard 我在其中验证标头中的令牌:

import { JwtService } from '@nestjs/jwt';
import {
  CanActivate,
  ExecutionContext,
  UnauthorizedException
} from '@nestjs/common';
import { Observable } from 'rxjs';

export class JwtAuthGuard implements CanActivate {
  constructor(private jwtService: JwtService) {}

  canActivate(
    context: ExecutionContext
  ): boolean | Promise<boolean> | Observable<boolean> {
    const req = context.switchToHttp().getRequest();

    try {
      const authHeader = req.headers.authorization;
      const token = authHeader.split(' ')[1];

      const user = this.jwtService.verify(token);

      req.user = user;
      return true;
    } catch (error) {
      console.log(error);
      throw new UnauthorizedException();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我的控制器:

import { …
Run Code Online (Sandbox Code Playgroud)

jwt typescript nestjs

2
推荐指数
1
解决办法
1349
查看次数

如何在 NestJS 中热重载联合网关

问题

在联合嵌套应用程序中,网关收集来自其他服务的所有架构并形成完整的图。问题是,子模式更改后如何重新运行模式集合?

当前的解决方法

重新启动网关可以解决问题,但这似乎不是一个优雅的解决方案。

其他资源

  1. Apollo 服务器支持托管联合,这本质上恢复了网关和服务之间的依赖关系。遗憾的是我找不到任何与 NestJS 相关的内容。

graphql nestjs apollo-federation

2
推荐指数
1
解决办法
1486
查看次数

有没有办法在 Nest JS 的装饰器中获取请求上下文

我正在尝试构建一个装饰器来“记录”请求信息

export const Tracking = () => {
  return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
    const method = descriptor.value;
    descriptor.value = async function(...args: any[]) {
      console.log(/** Request info */)
      console.log(/** Headers, Body, Method, URL...*/)
      return method.call(this, ...args);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

并尝试在这样的控制器方法上使用它。

export class Controller {

  @Get('/path')
  @Tracking()
  public async getData(@Headers('user') user: User) {
    return this.service.getData(user.id);
  }
}
Run Code Online (Sandbox Code Playgroud)

如果这是不可能的,有没有办法将拦截器应用于控制器的某些方法?
或者是否存在用于请求的线程(类似)级上下文?

谢谢!!

node.js typescript nestjs

2
推荐指数
1
解决办法
4640
查看次数

Nestjs:无法异步连接mongo

我无法异步连接到 mongodb。请让我知道我做错了什么。

蒙戈配置文件:

import { MongooseModuleOptions } from '@nestjs/mongoose';

export default (): { mongoConfig: MongooseModuleOptions } => ({
  mongoConfig: {
    uri: process.env.DB_URI,
    connectionName: 'learn-nest',
    useCreateIndex: true,
    useUnifiedTopology: true,
    useFindAndModify: false,
    useNewUrlParser: true,
  },
});

Run Code Online (Sandbox Code Playgroud)

这是应用程序模块内部编写的代码

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: ['.env'],
      isGlobal: true,
      cache: true,
    }),
    MongooseModule.forRootAsync({ …
Run Code Online (Sandbox Code Playgroud)

nestjs nestjs-config

2
推荐指数
1
解决办法
5200
查看次数

使用 JWT 策略的 NestJs 身份验证 - 添加“ignoreNotBefore”验证选项

我在 NestJs 中使用 AuthGuard 来验证请求 jwt 令牌。因为我的服务只是验证令牌而不是创建它,所以它不能使用“nbf”验证,以避免创建令牌的服务器的时间晚于我的服务器的情况。

当使用 jsonwebtoken 库使用纯 Node.js 时,可以轻松添加选项来关闭此验证,方法是添加:

jwt.verify(token, cert, {ignoreNotBefore: true})
Run Code Online (Sandbox Code Playgroud)

这也有效。但是,我该如何使用 Nest 来做到这一点呢?

这是我的守卫:

    @Injectable()
    export class JwtAuthGuard extends AuthGuard('jwt') {

     constructor(private reflector: Reflector,
              private authService: AuthService) {
       super();
     }

     async canActivate(context: ExecutionContext) {
       const isValid = await super.canActivate(context);
       return isValid;
     }

     handleRequest(err, user, info) {
       if (err || !user) {
         Logger.error(`Unauthorized: ${info && info.message}`);
         throw err || new UnauthorizedException();
      }
      return user;
    }
   }
Run Code Online (Sandbox Code Playgroud)

在JWT策略中,我尝试在调用PassportStrategy的“super”时添加ignoreNotBefore选项,但这不起作用:

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private …
Run Code Online (Sandbox Code Playgroud)

node.js nestjs nestjs-jwt

2
推荐指数
1
解决办法
1万
查看次数

NestJs - 从自定义装饰器内的服务调用方法

基于这个答案,我尝试在装饰器内实现另一个服务的功能。

这是我的尝试:

export function ClearCache() {
  const injectCacheService = Inject(CacheService);

  return (target: any, _: string, propertyDescriptor: PropertyDescriptor) => {
    injectCacheService(target, 'service'); // this is the same as using constructor(private readonly logger: LoggerService) in a class

    //get original method
    const originalMethod = propertyDescriptor.value;

    //redefine descriptor value within own function block
    propertyDescriptor.value = async function (...args: any[]) {
      try {
        console.log(this);
        const service: CacheService = this.service;
        service.clearCacheById(args[1]);

        return await originalMethod.apply(this, args);
      } catch (error) {
        console.error(error);
      }
    };
  };
} …
Run Code Online (Sandbox Code Playgroud)

decorator node.js typescript nestjs

2
推荐指数
1
解决办法
7569
查看次数

微服务客户端在 Nest.js 的动态配置模块中注册并通过参数加载到服务中

shared在应用程序中使用了具有动态配置的模块。共享模块包含interceptorservice其中包含从共享参数配置的客户端。我通过预定义名称将 注入service到 中interceptorSharedModule动态导入到 中SecondAppModule)。所以客户名称可以有不同的值。在服务内部,我需要在客户端注入之前知道客户端的名称。现在它是硬编码的:

@Injectable()
export class SumClientService {
    constructor(@Inject('MATH_SERVICE') private client: ClientProxy) {
        console.log('[SumClientService] - created')
    }

    sumCalculation(row: number[]): Observable<number> {
        return this.client.send<number>({ cmd: 'sum' }, row);
    }
}

Run Code Online (Sandbox Code Playgroud)

问题

如果名称仅在构造时已知,是否有任何方法可以按名称从上下文加载服务?

我在列表中检测到两种方法可以将名称作为参数传递到服务中,而不会破坏nest.js. 但我不知道如何访问模块上下文以按指定名称加载服务(想法片段的代码如下)

@Injectable()
export class SumClientService {
    constructor(@Inject('service_name') private name: string) {
        console.log('[SumClientService] - created')
        
    }
    client: (clientName: string) => ClientProxy = (clientName: string): ClientProxy => // TODO load by clientName real …
Run Code Online (Sandbox Code Playgroud)

ioc-container microservices nestjs

2
推荐指数
1
解决办法
4445
查看次数