GoogleCloudPlatform / functions-framework-nodejs

FaaS (Function as a service) framework for writing portable Node.js functions
Apache License 2.0
1.29k stars 158 forks source link

Implicit Request interface extension causes error 'property rawBody does not exist on type' #198

Open dobromyslov opened 4 years ago

dobromyslov commented 4 years ago

Cloud functions implicitly extend express Request interface with rawBody (see https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/master/src/invoker.ts#L44):

// We optionally annotate the express Request with a rawBody field.
// Express leaves the Express namespace open to allow merging of new fields.
declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace Express {
    export interface Request {
      rawBody?: Buffer;
    }
  }
}

I get error Property 'rawBody' does not exist on type 'Request<ParamsDictionary>' when implement handler which uses Request.rawBody attribute like below:

import {Response, Request} from 'express';

export class HandlerClass{
  public async http(request: Request, response: Response): Promise<void> {
    const body = request.rawBody;
    ...
  }
}

As a workaround I have to create and use my own type instead of native Express Request:

import * as express from 'express';

export interface Request extends express.Request {
  rawBody: Buffer;
}

If you have a look at the firebase-functions repository then you will see they use explicit extension of Request interface and then use it in code (https://github.com/firebase/firebase-functions/blob/master/src/providers/https.ts#L33)

I think functions-framework-nodejs should change implicit interface extension to explicit and provide stand-alone Request with rawBody attribute to avoid this workaround mess in depended applications code.

grant commented 4 years ago

Hey @dobromyslov, yeah that does look like an error with the TS interfaces.

I believe this workaround was just to fix the TS compiler, I don't think we really expected anybody to use our Request interface.

Want to send a PR, just changing the interfaces?

dobromyslov commented 4 years ago

Yes, I will prepare PR and send it in a couple of days.

I implemented custom handling of rawBody in TypeScript and found this issue.