Serverless

Run serverless applications and REST APIs using your existing Fastify application.

Attention Readers:

Fastify is not designed to run on serverless environments. The Fastify framework is designed to make implementing a traditional HTTP/S server easy. Serverless environments requests differently than a standard HTTP/S server; thus, we cannot guarantee it will work as expected with Fastify. Regardless, based on the examples given in this document, it is possible to use Fastify in a serverless environment. Again, keep in mind that this is not Fastify's intended use case and we do not test for such integration scenarios.

AWS Lambda

The sample provided allows you to easily build serverless web applications/services and RESTful APIs using Fastify on top of AWS Lambda and Amazon API Gateway.

Note: This is just one possible way.

app.js

  1. const fastify = require('fastify');
  2. function init(serverFactory) {
  3. const app = fastify({ serverFactory });
  4. app.get('/', (request, reply) => reply.send({ hello: 'world' }));
  5. return app;
  6. }
  7. if (require.main !== module) {
  8. // called directly i.e. "node app"
  9. init().listen(3000, (err) => {
  10. if (err) console.error(err);
  11. console.log('server listening on 3000');
  12. });
  13. } else {
  14. // required as a module => executed on aws lambda
  15. module.exports = init;
  16. }

You can simply wrap your initialization code by offering to inject an optional serverFactory.

When executed in your lambda function we don't need to listen to a specific port, so we just export the wrapper function init in this case. The lambda.js file will use this export.

When you execute your Fastify application like always, i.e. node app.js (the detection for this could be require.main === module), you can normally listen to your port, so you can still run your Fastify function locally.

lambda.js

  1. const awsServerlessExpress = require('aws-serverless-express');
  2. const init = require('./app');
  3. let server;
  4. const serverFactory = (handler) => {
  5. server = awsServerlessExpress.createServer(handler);
  6. return server;
  7. }
  8. const app = init(serverFactory);
  9. exports.handler = (event, context, callback) => {
  10. context.callbackWaitsForEmptyEventLoop = false;
  11. app.ready((e) => {
  12. if (e) return console.error(e.stack || e);
  13. awsServerlessExpress.proxy(server, event, context, 'CALLBACK', callback);
  14. });
  15. };

We define a custom serverFactory function, in which we create a new server with the help of aws-serverless-express (make sure you install the dependency npm i —save aws-serverless-express). Then we call the init function (imported from app.js) with the serverFactory function as the only parameter. Finally inside the lambda handler function we wait for the Fastify app to be ready and proxy all the incoming events (API Gateway requests) to the proxy function from aws-serverless-express.

Example

An example deployable with claudia.js can be found here.

Considerations

  • API Gateway doesn't support streams yet, so you're not able to handle streams.
  • API Gateway has a timeout of 29 seconds, so it's important to provide a reply during this time.