Nest: Issue with http request on zeit v2

Created on 27 Mar 2020  路  13Comments  路  Source: nestjs/nest

Bug Report

Current behavior

Nest http service failing to make a http requests when using '.subscribe()' when deploy on zeit v2

Input Code

  @Post('subscribe')
  subscribe(@Body() data: any, @Req() request: Request): void {
    Logger.log(data); // this works in v2

    // the rest does not work in v2
    this.httpService.put('https://webhook.site/03ec0f5c-603e-4fcd-b5d7-e2281d22a324',
      data,
      { headers: this.appService.getHeaders() }
    ).pipe(
      catchError(e => {
        Logger.log(this.appService.getStatus('[POST] /subscribe, error', e.response));
        Logger.log(e);
        throw new HttpException(e.response.statusText, e.response.status);
      }))
      .subscribe((x) => {
        Logger.log(this.appService.getStatus('[POST] /subscribe, success', x));
    })
  }

Expected behavior

The same code was working on v1 so it should work on v2

Possible Solution

I did refactor the code slightly and find out that it works on v2

 @Post('map')
  map(@Body() data: any, @Req() request: Request): Observable<"error" | "success"> {
    Logger.log(data);

    return this.httpService.put('https://webhook.site/03ec0f5c-603e-4fcd-b5d7-e2281d22a324',
      data,
      { headers: this.appService.getHeaders() }
    ).pipe(
      catchError(e => {
        Logger.log(this.appService.getStatus('[POST] /map, error', e.response));
        Logger.log(e);
        return of('error')
      }),
      map((x) => {
        if(x !== 'error'){
          Logger.log(this.appService.getStatus('[POST] /map, success', x));
          return 'success';
        } else {
          return 'error';
        }
    }))
  }

Environment


Nest version: 7.0.2

For Tooling issues:

  • Platform: Zeit 2.0

Others:

Here is a repo https://github.com/kuncevic/nestjs-zeit-http-issue
you can just push the dist to zeit v2 it is all ready to go, you can find configs for both v1 and v2 in deploy folder

You can use test.http to run requests within vscode using https://marketplace.visualstudio.com/items?itemName=humao.rest-client
In case if internal http request works you will see the result here https://webhook.site/#!/03ec0f5c-603e-4fcd-b5d7-e2281d22a324/

needs triage

All 13 comments

Can you please report this issue in the zeit repository? This doesn't seem to be related to NestJS.

Besides, HttpService uses axios under the hood so perhaps, there's a similar issue in their repo already.

@kamilmysliwiec I spoke with support before then, they said it is nestjs internal error.

This is not a NestJS internal error if it works properly on every other existing platform. I would love to help you somehow, but it's clear that this issue isn't related to Nest. You can ask on our Discord channel (support). Maybe someone else has a better idea of what could fix your problem.

@kamilmysliwiec ok, no probs, I have send the link to that issue to zeit support, hopefully they comeback with some input on that

Hello everyone,

To be clear, we didn't blame Nest.js for the error here at all. Now 2.0 is a serverless environment and frameworks like Nest.js are not a good fit for it since they are more aimed for "monolithic" and serverful apps. We require a function to export a handler, eg:

module.exports = (req, res) => {}

For that reason, we don't think Nest.js is a good fit for our platform at all. it is more suited for minimal frameworks, vanilla Node, etc.

We are in touch with @kuncevic and if anyone has any questions, just give us a shout.

@paulogdm You can run Nest in any serverless environment. Most platforms require to export a handler and this is obviously feasible with Nest as well (at least works pretty well with Azure, AWS, GCP).

@kamilmysliwiec For sure. We are aware of that. But the way the framework builds the output of a Nest.js app is not compatible with the standards of our platform. Here are a few points:

  • Per-endpoint granularity. We require that each path or pattern be served by a single serverless function. So that way your app scales better when adding more routes since more functions will be generated. As far as I'm aware, a Nest.js app would be "monolithic" when deployed to our platform since it would handle routing in itself.
  • Keep things minimal. Since one function can handle a single path, you can make it as minimal as possible in order to boost the performance of cold starts.

For more information, check the Next.js API feature.

Just wanted to add one thing:

Per-endpoint granularity. We require that each path or pattern be served by a single serverless function. So that way your app scales better when adding more routes since more functions will be generated.

More functions do not always mean that app scales better.

Anyways, what you said will be possible with this module https://github.com/nestjs/serverless-core

@kamilmysliwiec serverless-core looking interesting, so how would you approach it in that particular use case? I didn't found any docs on that.

More functions do not always mean that app scales better.

It scales in the sense of you avoiding one function to handle every route.

More functions do not always mean that app scales better.

Separating your app into isolated functions means each function handles less code logic and is hence smaller in size. This will translate into faster functions (in terms of booting it up) and also means your function is less likely to run into errors due to bugs in code created to handle other logics.

@williamli I know. But still, this doesn't mean that it always "scales better". "Scales better" is a very general term that doesn't always apply to serverless functions. Please, note that I'm not saying it's a wrong approach, I'm only referring to this sentence:

Per-endpoint granularity. We require that each path or pattern be served by a single serverless function. So that way your app scales better when adding more routes since more functions will be generated.

which isn't true because it simply depends on many factors.

Bug Report

Current behavior

Nest http service failing to make a http requests when using '.subscribe()' when deploy on zeit v2

Input Code

  @Post('subscribe')
  subscribe(@Body() data: any, @Req() request: Request): void {
    Logger.log(data); // this works in v2

    // the rest does not work in v2
    this.httpService.put('https://webhook.site/03ec0f5c-603e-4fcd-b5d7-e2281d22a324',
      data,
      { headers: this.appService.getHeaders() }
    ).pipe(
      catchError(e => {
        Logger.log(this.appService.getStatus('[POST] /subscribe, error', e.response));
        Logger.log(e);
        throw new HttpException(e.response.statusText, e.response.status);
      }))
      .subscribe((x) => {
        Logger.log(this.appService.getStatus('[POST] /subscribe, success', x));
    })
  }

@kuncevic FYI, you need to wrap your httpService inside a await/async pattern to prevent it from running asynchronously since your function will get terminated once the main thread returns, killing all other async threads that are still running.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rafal-rudnicki picture rafal-rudnicki  路  3Comments

yanshuf0 picture yanshuf0  路  3Comments

artaommahe picture artaommahe  路  3Comments

thohoh picture thohoh  路  3Comments

cojack picture cojack  路  3Comments