cyrilwanner / next-serverless

☁️ next-serverless deploys your next.js application to AWS Lambda with minimal or even no configuration.
MIT License
81 stars 7 forks source link

Access event and callback #5

Open tzehe opened 5 years ago

tzehe commented 5 years ago

Hi,

first of all thank you for this amazing project! I am using to deploy a small next.js app to lambda in production. I want to use serverless-plugin-warmup to prevent cold starts in production. To reduce costs as stated here (https://serverless.com/blog/keep-your-lambdas-warm/) I try to add this logic to my lambda function:

module.exports.lambdaToWarm = function(event, context, callback) {
  /** Immediate response for WarmUP plugin */
  if (event.source === 'serverless-plugin-warmup') {
    console.log('WarmUP - Lambda is warm!')
    return callback(null, 'Lambda is warm!')
  }

  ... add lambda logic after
}

I noticed that the logic is wrapped around in handler.js. Is there a simple solution to achieve this.

Thanks in advance!

cyrilwanner commented 5 years ago

Hi @tzehe Do you also use a custom (next) server? If yes, I think you should be able to just call the nextServerless method which you would have to call anyway then. So from the example, it should look like this:

// server code here..

// create the nextServerless handler
const nextServerlessHandler = nextServerless(app, requestHandler, () => {
  // create a normal http node server for local usage
  createServer(requestHandler).listen(3000, (err) => {
    if (err) throw err;
    console.log('> Ready on http://localhost:3000');
  });
});

// export the nextServerless function
module.exports.handler = function(event, context, callback) {
  /** Immediate response for WarmUP plugin */
  if (event.source === 'serverless-plugin-warmup') {
    console.log('WarmUP - Lambda is warm!')
    return callback(null, 'Lambda is warm!')
  }

  // call the normal logic otherwise
  return nextServerlessHandler(event, context, callback);
}

If you do not use a custom server, you may be able to import the default logic like this:

const { handler as nextServerless } = require('next-serverless/lib/next/server');

// ...

module.exports.lambdaToWarm = function(event, context, callback) {
  /** Immediate response for WarmUP plugin */
  if (event.source === 'serverless-plugin-warmup') {
    console.log('WarmUP - Lambda is warm!')
    return callback(null, 'Lambda is warm!')
  }

  return nextServerless(event, context, callback);
}

I didn't test those codes, but I think it can work. Please tell me when it doesn't, I'll then try to debug it and release a patch to be able to hook into the event.

Anyway, when we found a solution, I'll add an example to the readme. I didn't yet think about this use-case, so thank you for sharing :)

cyrilwanner commented 5 years ago

I just noticed an error and updated the code above

tzehe commented 5 years ago

Hey @cyrilwanner thank you for your detailed response. I am using a custom server and will try your approach. I will get back to you afterwards.

Thank you!

tzehe commented 5 years ago

Hey @cyrilwanner I implemented your suggested solution and it worked perfectly for me. I checked my cloudwatch logs and it shows the log messages if the lambda is warm. So thank you for your help an I am glad to help you with this use case. Would be beneficial to add this to the documentation. 😊

cyrilwanner commented 5 years ago

Perfect, thank you! Yes, it really would, I'll add it to the documentation and add an example project with the next version.