dougmoscrop / serverless-http

Use your existing middleware framework (e.g. Express, Koa) in AWS Lambda 🎉
Other
1.72k stars 165 forks source link

Adding Lambda Edge origin request to AWS #192

Closed eelayoubi closed 2 years ago

eelayoubi commented 3 years ago

In this PR, I did the following:

The change:

serverless(app, { provider: 'aws', type: 'lambda-edge-origin-request' });

Will result in using the Lambda edge to process the calls. If no type is provided the default is to use api-gw integration:

module.exports = options => { if (options.type === 'lambda-edge-origin-request') { return lambdaEdgeOriginRequest(options) } else { return apiGw(options) } };

alexcroox commented 3 years ago

Disclaimer; excuse my ignorance I've only used this library a few days and don't fully understand it.

I've used your master branch version as I'm experiencing issues with lambda@edge + Nuxt and the response headers not being in the new array format. Your version seems to correctly fix that, except for one header:

image

I imagine set-cookie is being set by the Nuxt framework, and maybe this middleware is being triggered before it's own. Is there any way to make sure your transformations on the response headers are the last? Or should I write my own header transforms in the module.exports.handler just before it returns to guarantee they are all transformed to the array format?

eelayoubi commented 3 years ago

@alexcroox I am testing using angular, and express for SSR, and in express I just set a cookie to test if it will be returned correctly to the client.

Express js:

// All regular routes use the Universal engine
app.get('*', (req, res) => {
    res.cookie('test', 'lala');
    fs.readFile(join(__dirname, '../browser/index.html'), function (err, html) {
        if (err) {
            throw err;
        }

        renderModule(AppServerModule, {
            document: html.toString(),
            url: req.url
        }).then((html) => {
            res.send(html);
        });
    });

});

This is the returned response from lambda:

{
  status: '200',
  statusDescription: 'OK',
  headers: {
    'x-powered-by': [ [Object] ],
    'set-cookie': [ [Object] ],
    'content-type': [ [Object] ],
    etag: [ [Object] ]
  },
  body: '.........'
alexcroox commented 3 years ago

This is how I'm using it:

const serverless = require('serverless-http')
const express = require('express')
const { Nuxt } = require('nuxt-start')

// Import and overwrite nuxt options
const config = require('../nuxt.config.js')

config.render = { etag: true, compressor: { threshold: Infinity } }
config.dev = false

// Create nuxt instance
const nuxt = new Nuxt(config)

// Create Express instance
const app = express()

// Add nuxt.render as express middleware
app.use(nuxt.render)

const handler = serverless(app, {
  type: 'lambda-edge-origin-request',
  platform: 'aws'
})

module.exports.handler = async (event, context) => {
  // Make sure nuxt is ready to handle requests
  await nuxt.ready()

  // Execute handler
  return await handler(event, context)
}

But I'm sure it's down to the lifecycle order of serverless/Nuxt that is causing the issue rather than anything in your PR, so I'll stop derailing this PR and leave it there, thanks though!

dougmoscrop commented 2 years ago

Closing in favour of #196