【问题标题】:How to properly use Observables with nestjs?如何正确使用带有 Nestjs 的 Observables?
【发布时间】:2020-09-30 03:44:22
【问题描述】:

我正在开发一个 API,它可以处理用户(只是为了简单起见)进行基本的 crud 操作。 我得到了类似的用户服务:

    @Injectable()
    export class UsersService {
        constructor(
            @InjectRepository(User)
            private usersRepository: Repository<User>,
        ) { }
...
        async findById(id: number): Promise<User> {
            return this.usersRepository.findOne(id);
    }

和一个控制器:

@UseGuards(JwtAuthGuard)
@UseInterceptors(ClassSerializerInterceptor)
@UseFilters(QueryFailedExceptionFilter)
@Controller('users')
export class UsersController {

    constructor(private readonly _userService: UsersService) { }

 @Get(':id')
    findById(@Param('id', ParseIntPipe) id: number): Observable<User> {
        return from(this._userService.findById(id));
    }

这行得通,我可以找到、创建、删除等。问题是,如果我尝试从我的控制器获取 finOne 用户(Get(:id))并且如果它不存在,它只会返回 200 ok没有响应客户端,但应该是404,因为找不到资源。

阅读我理解的文档(希望我做对了),我们可以返回一个 observable,它会被自动订阅。所以问题是,如果 findOne 的结果是空的,在哪里以及如何处理,并返回一个具有适当状态的响应,当然使用 observables。

我试图找到一些示例,但我只找到了一些使用 Promise 的示例,并且大多数时候他们只是忽略了 not find 用户案例。

PD:“他们”说我应该在控制器中处理它

【问题讨论】:

    标签: javascript nestjs


    【解决方案1】:

    如果你想返回 404 并使用 observables,你可以这样做:

    @UseGuards(JwtAuthGuard)
    @UseInterceptors(ClassSerializerInterceptor)
    @UseFilters(QueryFailedExceptionFilter)
    @Controller('users')
    export class UsersController {
    
        constructor(private readonly _userService: UsersService) { }
    
     @Get(':id')
        findById(@Param('id', ParseIntPipe) id: number): Observable<User> {
            return from(this._userService.findById(id)).pipe(
              map(user => {
                if (!user) {
                  throw new NotFoundException();
                }
                return user;
              })
            );
        }
    

    我个人非常喜欢将我的所有逻辑都保留在服务中而不是控制器中,这样可以使控制器保持精简并且大部分逻辑可重用。

    【讨论】:

    • 很快,谢谢。好的,它有效,我想我必须深入了解运营商。唯一的问题是响应状态始终为 400 异常。我知道我可以使用 @Res() 来设置状态,但我一点也不喜欢它,并且想避免使用特定的库方法。顺便说一句,我同意您关于“将我的所有逻辑保留在服务中”的观点,但例如,如果我使用基类来处理所有服务的查找、删除、更新等基本操作,并且还想在响应时发送自定义消息我认为在这种情况下,在控制器上这样做可能是正确的。
    • 我认为我可以使用全局异常过滤器处理异常并更改那里的状态代码......只是不确定这是否是最好的方法。
    • 当我使用NotFoundException在本地机器上尝试时,我得到了正确的 404 回复
    • 是的,你是对的。我正在使用过滤器捕获所有错误并将响应设置为 400(我更改为我想要处理的特定异常,现在它可以工作了),我的错误。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2022-01-19
    • 2020-12-22
    • 2014-12-20
    • 1970-01-01
    • 2020-04-15
    • 2019-03-17
    • 2016-05-26
    • 2020-04-26
    相关资源
    最近更新 更多