Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to deploy on Firebase Functions/Google Cloud Functions #946

Closed
endigo opened this issue May 21, 2018 · 50 comments
Closed

How to deploy on Firebase Functions/Google Cloud Functions #946

endigo opened this issue May 21, 2018 · 50 comments
Labels
question General question about the project stale Issue or pr with more than 15 days of inactivity.

Comments

@endigo
Copy link

endigo commented May 21, 2018

How to run the server from cloud functions?

in express

const server = express();
exports.next = functions.https.onRequest((request, response) => {
	server(request,response);
});
@nwoltman
Copy link
Contributor

This is not possible currently. #804 is a similar issue.

@delvedor delvedor added the question General question about the project label May 22, 2018
@delvedor
Copy link
Member

We are working on that feature in #937.

@vincent178
Copy link
Member

One more PR #960

@stale
Copy link

stale bot commented Jun 19, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale Issue or pr with more than 15 days of inactivity. label Jun 19, 2018
@delvedor
Copy link
Member

@endigo in the latest version of Fastify (v1.6.0) you can use the serverFactory option. It should help you.

Closing this, please feel free to reopen if you have other questions :)

@shwei
Copy link
Contributor

shwei commented Jan 15, 2019

@delvedor @mcollina would love to have some pointers to actually use fastify in Cloud Functions. The typical call for http triggered functions is done by calling Functions' built-in onRequest method:
const functions = require('firebase-functions'); ... exports.greetFromFastify = functions.https.onRequest(fastify);

The full code example is at https://gist.github.com/shwei/d34c7383a117451c07dc701ad12482f1

Is there a way I can make this happens with Fastify? Thank you all.

@mcollina
Copy link
Member

@shwei
Copy link
Contributor

shwei commented Jan 15, 2019

@mcollina thanks, but I don't know how to pass the given handler from serverFactory out to onRequest. Here is what I've so far https://gist.github.com/shwei/d34c7383a117451c07dc701ad12482f1#file-fastify-in-firebase-function-js-L14

I know this is not what you're asking. But at this point I don't know the core concept I'm missing to understand this better. If you know, please let me know! Thanks again!

@mtermoul
Copy link

mtermoul commented Feb 6, 2019

is this fixed yet? I tried to use the serverFactory as pointed out by @shwei but it's not working! Can you please provide me with a code example?
This is my code:

const functions = require('firebase-functions')
const http = require('http')
const Fastify = require('fastify')

exports.app = functions.https.onRequest((req, res) => {
    const serverFactory = (handler, opts) => {
      const server = http.createServer((req, res) => {
        handler(req, res)
      })
      return server
    }
    const fastify = Fastify({serverFactory})
    fastify.get('/', (req, reply) => {
      reply.send({ hello: 'world' })
    })
})

I am getting Timed out waiting for function to respond. error

@nwoltman
Copy link
Contributor

nwoltman commented Feb 6, 2019

@mtermoul Something like this should work:

const functions = require('firebase-functions')
const http = require('http')
const Fastify = require('fastify')

let handleRequest = null

const serverFactory = (handler, opts) => {
  handleRequest = handler
  return http.createServer()
}
const fastify = Fastify({serverFactory})

fastify.get('/', (req, reply) => {
  reply.send({ hello: 'world' })
})

exports.app = functions.https.onRequest((req, res) => {
  fastify.ready((err) => {
    if (err) throw err
    handleRequest(req, res)
  })
})

This is more efficient as well since it doesn't create a new Fastify instance on every request.

@shwei
Copy link
Contributor

shwei commented Feb 7, 2019

Thanks @nwoltman! This is very helpful. I had to put in the line before fastify.ready() call:

  req = Object.assign({ip: ''}, {...req}); 

  fastify.ready((err) => {
  ...

Without that hacky line, I would get the error:

error: /Users/shwei/Work/workspace/cf-fastify-restify-express/functions/node_modules/fastify/fastify.js:249
    
req.ip = req.connection.remoteAddress
       ^
TypeError: Cannot set property ip of [object Object] which has only a getter
        at _ipAsRemoteAddress (/Users/shwei/Work/workspace/cf-fastify-restify-express/functions/node_modules/fastify/fastify.js:249:12)

Is there a way to avoid this error?

full code

@mtermoul: thanks for following up with this man.

@mtermoul Something like this should work:

const functions = require('firebase-functions')
const http = require('http')
const Fastify = require('fastify')

let handleRequest = null

const serverFactory = (handler, opts) => {
  handleRequest = handler
  return http.createServer()
}
const fastify = Fastify({serverFactory})

fastify.get('/', (req, reply) => {
  reply.send({ hello: 'world' })
})

exports.app = functions.https.onRequest((req, res) => {
  fastify.ready((err) => {
    if (err) throw err
    handleRequest(req, res)
  })
})

This is more efficient as well since it doesn't create a new Fastify instance on every request.

@mtermoul
Copy link

mtermoul commented Feb 9, 2019

Thank you guys @nwoltman 🙌 👍 🏆 and @shwei 🌟 🎉 🎆 for the code sample. Fastify is finally working with cloud functions. And now going back to implement the real features and see how would Fastify hold.

@nwoltman
Copy link
Contributor

nwoltman commented Feb 9, 2019

@shwei It looks like that error happens because firebase-functions passes Express's prototype-extended req and res objects to the handler function, but Fastify expects to receive Node's native req and res objects.

@fastify/fastify What do you think is the right thing to do here? Is this a problem that should be fixed in Fastify?

@shwei
Copy link
Contributor

shwei commented Feb 10, 2019

Thanks for looking into this @nwoltman . If this can be accommodated without too much sacrifice on performance, it would allow greater compatibility with one of very popular serverless infrastructures.

Or maybe if we could pass an option to skip setting req.ip?

@shwei It looks like that error happens because firebase-functions passes Express's prototype-extended req and res objects to the handler function, but Fastify expects to receive Node's native req and res objects.

@fastify/fastify What do you think is the right thing to do here? Is this a problem that should be fixed in Fastify?

@nwoltman
Copy link
Contributor

Another solution would be to set ip on the Fastify request object instead of Node's req object. @delvedor originally suggested this in #1086.

@shwei
Copy link
Contributor

shwei commented Feb 11, 2019

@nwoltman when you said, "set ip on the Fastify request object", can you elaborate it a little more? Did you mean set trustProxy?

const fastify = Fastify({ trustProxy: true })
// OR given IP/CIDR?
const fastify = Fastify({ trustProxy: '${IP/CIDR}' })

Thanks!

Another solution would be to set ip on the Fastify request object instead of Node's req object. @delvedor originally suggested this in #1086.

@nwoltman
Copy link
Contributor

@shwei Yes, it's related to the trustProxy option. I'm suggesting that a solution would be to pass ip to Fastify's Request constructor here:

var request = new context.Request(params, req, query, req.headers, req.log)

rather than setting it on Node's req object here:

fastify/fastify.js

Lines 273 to 283 in 356cf6f

function _handleTrustProxy (req) {
req.ip = proxyAddr(req, proxyFn)
req.ips = proxyAddr.all(req, proxyFn)
if (req.ip !== undefined) {
req.hostname = req.headers['x-forwarded-host']
}
}
function _ipAsRemoteAddress (req) {
req.ip = req.connection.remoteAddress
}

Of course, if that were done, ips and hostname would also need to move to the Fastify Request object.

@shwei
Copy link
Contributor

shwei commented Feb 12, 2019

@nwoltman Interesting with passing ip in the context.Request call! It sounds like handleTrustProxy(req) may need to be tweaked. What are the steps we need to incorporate your proposed change? Anything I can do to help?

Another idea: if req.ip has a value and if there is an option we can pass into fastify to indicate that we want to skip calling the method handleTrustProxy(req), we can just keep both _handleTrustProxy and _ipAsRemoteAddress unchanged. However, it will require a new logic and it can be too hacky and short-term.

Express's prototype-extended req has an ip value in
https://gist.github.com/shwei/d34c7383a117451c07dc701ad12482f1#file-fastify-js-L28

@shwei Yes, it's related to the trustProxy option. I'm suggesting that a solution would be to pass ip to Fastify's Request constructor here:
fastify/fastify.js

Line 307 in 356cf6f

var request = new context.Request(params, req, query, req.headers, req.log)

rather than setting it on Node's req object here:
fastify/fastify.js

Lines 273 to 283 in 356cf6f

function _handleTrustProxy (req) {
req.ip = proxyAddr(req, proxyFn)
req.ips = proxyAddr.all(req, proxyFn)
if (req.ip !== undefined) {
req.hostname = req.headers['x-forwarded-host']
}
}

function _ipAsRemoteAddress (req) {
req.ip = req.connection.remoteAddress
}
Of course, if that were done, ips and hostname would also need to move to the Fastify Request object.

@nwoltman
Copy link
Contributor

@shwei Having an option that is only used to avoid setting a particular property does seem pretty hacky, especially when there's a non-hacky solution. I'd suggesting submitting a PR to move ip to Fastify's Request object. You can probably figure out how to do that by looking at #1086. If not, you can open a new issue for the bug so it can be addressed properly (our conversation doesn't really fit the original issue anymore).

@shwei
Copy link
Contributor

shwei commented Feb 23, 2019

Thank you, @nwoltman. Finally got around to work on this. I'm fairly new to fastify, so would you please take a look at my changes? shwei/fastify@88f4c8a Your comments are greatly appreciated.

@shwei Having an option that is only used to avoid setting a particular property does seem pretty hacky, especially when there's a non-hacky solution. I'd suggesting submitting a PR to move ip to Fastify's Request object. You can probably figure out how to do that by looking at #1086. If not, you can open a new issue for the bug so it can be addressed properly (our conversation doesn't really fit the original issue anymore).

@nwoltman
Copy link
Contributor

nwoltman commented Mar 5, 2019

Thanks @nwoltman! This is very helpful. I had to put in the line before fastify.ready() call:

  req = Object.assign({ip: ''}, {...req}); 

  fastify.ready((err) => {
  ...

Without that hacky line, I would get the error:

@shwei I found another way to avoid the error that's less likely to introduce other bugs.

Instead of

req = Object.assign({ip: ''}, {...req}); 

do

Object.defineProperty(req, 'ip', {
  value: req.ip,
  configurable: true,
  enumerable: true,
  writable: true,
});

This just modifies the ip property instead of creating a new object that doesn't share the same prototype as the req object.

@mcollina
Copy link
Member

mcollina commented Mar 5, 2019

Can you please explain to me what is the problem? I don’t understand.

@nwoltman
Copy link
Contributor

nwoltman commented Mar 5, 2019

The problem is that people who use Fastify with Google Cloud's Firebase Functions will run into this error on every request:

error: /functions/node_modules/fastify/fastify.js:249
    
req.ip = req.connection.remoteAddress
       ^
TypeError: Cannot set property ip of [object Object] which has only a getter
        at _ipAsRemoteAddress (/functions/node_modules/fastify/fastify.js:249:12)

This happens because Fastify is trying to set the req.ip property (here), but it fails because Firebase functions use the same req and res objects that Express uses. In Express, req.ip is defined only as a getter (see here), so trying to set that property is an error.

@mcollina
Copy link
Member

mcollina commented Mar 5, 2019

I’m happy to add an option to disable that. I think it should work.

@shwei
Copy link
Contributor

shwei commented Mar 5, 2019

By all means, please do if that makes most sense. Hope the new option will be available for 1.x. Let me know how I can help. Thanks!

@mcollina
Copy link
Member

mcollina commented Mar 6, 2019

@shwei can you update your PR in that direction? I'm happy to have the change backported.

@nwoltman
Copy link
Contributor

nwoltman commented Mar 6, 2019

@mcollina Just wondering, is the plan you're thinking of to:

  1. Add the option to @shwei's PR (Pass ip, ips, and hostname to Request object #1476) while still keeping his work to add the properties to Fastify's Request object
  2. Remove the option and remove the properties from the Node core req object in v3?

@mcollina
Copy link
Member

mcollina commented Mar 6, 2019

That’s the plan.

@nwoltman
Copy link
Contributor

nwoltman commented Mar 6, 2019

OK, that sounds good to me 🙂

@shwei
Copy link
Contributor

shwei commented Mar 6, 2019

@mcollina @nwoltman how does skipAssignIpInNodeReq in options sound? Any better names?

@mcollina
Copy link
Member

mcollina commented Mar 6, 2019

@shwei I would go one step further and do: addPropertiesToNodeReq, and avoid adding the logger as well while we are at it.

@shwei
Copy link
Contributor

shwei commented Mar 6, 2019

@mcollina would this option apply to res.log also?
req.log = res.log = log.child({ reqId: req.id, level: context.logLevel })
https://github.com/shwei/fastify/blob/pass-ip-to-request-constructor/fastify.js#L307

@mcollina
Copy link
Member

mcollina commented Mar 6, 2019

@shwei yes, I would actually go that far.

@jineshshah36
Copy link
Contributor

We just spent a considerable amount of time trying to get fastify running on google cloud functions, and then we discovered google cloud run which shares many of the benefits of cloud functions but works much more easily with fastify. You just specify a docker file and cloud run will run your dockerized fastify server like a serverless function. It took 10 minutes to setup and required no major code changes from how you would run fastify on a regular server

@Eomm
Copy link
Member

Eomm commented Jul 16, 2019

@jineshshah36 would you like to add your finding in the Serverless.md?

This would help the community for sure 💪

@jineshshah36
Copy link
Contributor

Yes, keep forgetting to do this. Will try to send a PR this weekend!

@jineshshah36
Copy link
Contributor

Done: #1770

@rfgamaral
Copy link

I understand it's a bit easier to configure fastify with Google Cloud Run due to it's container based approach. But I'm still wondering if any progress was made to better support fastify with Firebase Cloud functions for people that prefer the Firebase ecosystem?

@mcollina
Copy link
Member

I never had a chance. Would you like to investigate it and send a PR for the serverless docs?

@rfgamaral
Copy link

I never had a chance. Would you like to investigate it and send a PR for the serverless docs?

I'm unfamiliar with Fastify's code base and Fastify itself to be honest. So I'm not the right guy for the job. I was under the impression that either @shwei or @nwoltman were close to a solution...

@nwoltman
Copy link
Contributor

@rfgamaral It should work just fine if you set the modifyCoreObjects option to false.

@devotox
Copy link

devotox commented Aug 14, 2020

So for anybody who is having trouble on google cloud functions or firebase functions use this in your package.json

"@google-cloud/functions-framework": "devotox/google-cloud-functions-framework"

The problem with POST requests was that functions-framework already attached a body parser

@manasmishra
Copy link

So for anybody who is having trouble on google cloud functions or firebase functions use this in your package.json

"@google-cloud/functions-framework": "devotox/google-cloud-functions-framework"

The problem with POST requests was that functions-framework already attached a body parser

Any small working example will help the community a lot. How and where to use the above line?
Thanks.

@woobione
Copy link

woobione commented Jan 24, 2021

To this day, the issue @devotox mentions is present.
When running Fastify as a Google Cloud Function (firebase-functions), using the suggested serverFactory approach, all POST and PATCH requests will just never return anything, as long as the Content-Type header application/json is present. Thought I would share my findings for anyone else having the same issue.

The root of the problem is in contentTypeParser and more explicitly the rawBody method which (if parseAs is string or buffer) will try to read the buffer from the body. However, the buffer has already been read by body-parser in the firebase-functions library, hence netiher payload.on('data', onData) or payload.on('end', onEnd) will ever run, resulting in done never being called. Fully expected by Fastify, but until I figured it out I've been pulling my hair out for hours thinking I'm going crazy.

Since the rawBody will be run, even if you provide your own contentTypeParser, you can not mitigate it simply by sending a your own parser for application/json. BUT if you provide a parser which does NOT specify the parseAs option, you bypass that method. And since the body has already been parsed, a simple solution is to do the following:

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

Hope I can help someone else wanting to use this superb library together with cloud functions 🤗

Full Example Code

const functions = require('firebase-functions');
let requestHandler = null;

const fastify = require('fastify')({
  logger: true,
  serverFactory: (handler) => {
    requestHandler = handler;
    return require('http').createServer();
  },
});

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

fastify.post('/postToMeWithJSON', async (req) => {
  return req.body;
});

exports.myApi = functions.https.onRequest((req, res) => {
  fastify.ready((err) => {
    if (err) throw err;
    requestHandler(req, res);
  });
});

@nmggithub
Copy link

To this day, the issue @devotox mentions is present. When running Fastify as a Google Cloud Function (firebase-functions), using the suggested serverFactory approach, all POST and PATCH requests will just never return anything, as long as the Content-Type header application/json is present. Thought I would share my findings for anyone else having the same issue.

The root of the problem is in contentTypeParser and more explicitly the rawBody method which (if parseAs is string or buffer) will try to read the buffer from the body. However, the buffer has already been read by body-parser in the firebase-functions library, hence netiher payload.on('data', onData) or payload.on('end', onEnd) will ever run, resulting in done never being called. Fully expected by Fastify, but until I figured it out I've been pulling my hair out for hours thinking I'm going crazy.

Since the rawBody will be run, even if you provide your own contentTypeParser, you can not mitigate it simply by sending a your own parser for application/json. BUT if you provide a parser which does NOT specify the parseAs option, you bypass that method. And since the body has already been parsed, a simple solution is to do the following:

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

Hope I can help someone else wanting to use this superb library together with cloud functions hugs

Full Example Code

const functions = require('firebase-functions');
let requestHandler = null;

const fastify = require('fastify')({
  logger: true,
  serverFactory: (handler) => {
    requestHandler = handler;
    return require('http').createServer();
  },
});

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

fastify.post('/postToMeWithJSON', async (req) => {
  return req.body;
});

exports.myApi = functions.https.onRequest((req, res) => {
  fastify.ready((err) => {
    if (err) throw err;
    requestHandler(req, res);
  });
});

I second this. I am experiencing the same issues.

@manasmishra
Copy link

To this day, the issue @devotox mentions is present. When running Fastify as a Google Cloud Function (firebase-functions), using the suggested serverFactory approach, all POST and PATCH requests will just never return anything, as long as the Content-Type header application/json is present. Thought I would share my findings for anyone else having the same issue.
The root of the problem is in contentTypeParser and more explicitly the rawBody method which (if parseAs is string or buffer) will try to read the buffer from the body. However, the buffer has already been read by body-parser in the firebase-functions library, hence netiher payload.on('data', onData) or payload.on('end', onEnd) will ever run, resulting in done never being called. Fully expected by Fastify, but until I figured it out I've been pulling my hair out for hours thinking I'm going crazy.
Since the rawBody will be run, even if you provide your own contentTypeParser, you can not mitigate it simply by sending a your own parser for application/json. BUT if you provide a parser which does NOT specify the parseAs option, you bypass that method. And since the body has already been parsed, a simple solution is to do the following:

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

Hope I can help someone else wanting to use this superb library together with cloud functions hugs
Full Example Code

const functions = require('firebase-functions');
let requestHandler = null;

const fastify = require('fastify')({
  logger: true,
  serverFactory: (handler) => {
    requestHandler = handler;
    return require('http').createServer();
  },
});

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

fastify.post('/postToMeWithJSON', async (req) => {
  return req.body;
});

exports.myApi = functions.https.onRequest((req, res) => {
  fastify.ready((err) => {
    if (err) throw err;
    requestHandler(req, res);
  });
});

I second this. I am experiencing the same issues.

Great analysis. Thanks for the detailed solution.

@Taha-Firoz
Copy link

To this day, the issue @devotox mentions is present. When running Fastify as a Google Cloud Function (firebase-functions), using the suggested serverFactory approach, all POST and PATCH requests will just never return anything, as long as the Content-Type header application/json is present. Thought I would share my findings for anyone else having the same issue.

The root of the problem is in contentTypeParser and more explicitly the rawBody method which (if parseAs is string or buffer) will try to read the buffer from the body. However, the buffer has already been read by body-parser in the firebase-functions library, hence netiher payload.on('data', onData) or payload.on('end', onEnd) will ever run, resulting in done never being called. Fully expected by Fastify, but until I figured it out I've been pulling my hair out for hours thinking I'm going crazy.

Since the rawBody will be run, even if you provide your own contentTypeParser, you can not mitigate it simply by sending a your own parser for application/json. BUT if you provide a parser which does NOT specify the parseAs option, you bypass that method. And since the body has already been parsed, a simple solution is to do the following:

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

Hope I can help someone else wanting to use this superb library together with cloud functions 🤗

Full Example Code

const functions = require('firebase-functions');
let requestHandler = null;

const fastify = require('fastify')({
  logger: true,
  serverFactory: (handler) => {
    requestHandler = handler;
    return require('http').createServer();
  },
});

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

fastify.post('/postToMeWithJSON', async (req) => {
  return req.body;
});

exports.myApi = functions.https.onRequest((req, res) => {
  fastify.ready((err) => {
    if (err) throw err;
    requestHandler(req, res);
  });
});

this fix in no longer valid since body is now an incoming message and there is no body property on body. If the parseAs: 'string' parameter is passed into addContentTypeParser then the body can be parsed.

@joenoon
Copy link

joenoon commented Aug 5, 2022

To this day, the issue @devotox mentions is present. When running Fastify as a Google Cloud Function (firebase-functions), using the suggested serverFactory approach, all POST and PATCH requests will just never return anything, as long as the Content-Type header application/json is present. Thought I would share my findings for anyone else having the same issue.
The root of the problem is in contentTypeParser and more explicitly the rawBody method which (if parseAs is string or buffer) will try to read the buffer from the body. However, the buffer has already been read by body-parser in the firebase-functions library, hence netiher payload.on('data', onData) or payload.on('end', onEnd) will ever run, resulting in done never being called. Fully expected by Fastify, but until I figured it out I've been pulling my hair out for hours thinking I'm going crazy.
Since the rawBody will be run, even if you provide your own contentTypeParser, you can not mitigate it simply by sending a your own parser for application/json. BUT if you provide a parser which does NOT specify the parseAs option, you bypass that method. And since the body has already been parsed, a simple solution is to do the following:

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

Hope I can help someone else wanting to use this superb library together with cloud functions 🤗
Full Example Code

const functions = require('firebase-functions');
let requestHandler = null;

const fastify = require('fastify')({
  logger: true,
  serverFactory: (handler) => {
    requestHandler = handler;
    return require('http').createServer();
  },
});

fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
  done(null, body.body);
});

fastify.post('/postToMeWithJSON', async (req) => {
  return req.body;
});

exports.myApi = functions.https.onRequest((req, res) => {
  fastify.ready((err) => {
    if (err) throw err;
    requestHandler(req, res);
  });
});

this fix in no longer valid since body is now an incoming message and there is no body property on body. If the parseAs: 'string' parameter is passed into addContentTypeParser then the body can be parsed.

FWIW, body.body still works as of today, even though body is IncomingMessage, and the types say there is no body.body. I'm using done(null, (body as any).body) and have verified with console.log that (body as any).body does return the parsed object. Not sure why its not in the types.

@climba03003
Copy link
Member

climba03003 commented Aug 5, 2022

even though body is IncomingMessage, and the types say there is no body.body

The typings is correct since the body.body is added by firebase functions or goolgle cloud functions.
It is not a official property from node.

@HugoGresse
Copy link

HugoGresse commented Nov 18, 2023

this solution won't work (or the one from the doc) for multipart / file upload :/
the await request.file() or attaching the file to the body never works (undefined), but when calling fastify directly (and not through the firebase-function onRequest) it works.
Editing the fastify-multipart using this :

function setMultipart (req, body, done) {
  req[kMultipart] = true
  done(null, body.body)
}

Also won't correctly work and the body will stay as a Buffer in the route.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question General question about the project stale Issue or pr with more than 15 days of inactivity.
Projects
None yet
Development

No branches or pull requests