fastify / fastify-express

Express compatibility layer for Fastify
MIT License
247 stars 25 forks source link

Add support for wrapping Express req with Proxy #105

Closed tastypackets closed 1 year ago

tastypackets commented 1 year ago

Adds support for a Proxy around the Express request object.

It's difficult to migrate to Fastify from a complex set of Express middleware used by many services that have assumptions about some data being on the request object or expect to set data to the request that is consumed by other middleware.

Using Fastify server has resulted in some edge cases where it's not possible to easily migrate middleware A and not middleware B at the same time, moving both would be a huge effort and not very realistic todo at the same time. Adding a Proxy gives us the ability to let Express middleware read and write from Fastify decorators as a short term migration solution.

For example consider this snippet from the test file, it allows the Express middleware to read from both decorators and mutate the getAndSetFastify decorator which can then be used by Fastify plugins.

  fastify.decorateRequest('getAndSetFastify', 'original message')
  fastify.decorateRequest('getOnlyFastify',  'original message')

  fastify.register(expressPlugin, {
    createProxyHandler: fastifyReq => ({
      set (target, prop, value) {
        if (prop === 'getAndSetFastify') {
          return Reflect.set(fastifyReq, prop, value)
        } else if (prop === 'getOnlyFastify') {
          return true
        } else {
          return Reflect.set(target, prop, value)
        }
      },
      get (target, prop) {
        if (prop === 'getAndSetFastify' || prop === 'getOnlyFastify') {
          // Return something from Fastify req
          return fastifyReq[prop]
        }

        return target[prop]
      }
    })
  })
    .after(() => {
      fastify.use(function (req, res, next) {
        req.getAndSetFastify = 'updated'
        // This will NOT updated Fastify req
        req.getOnlyFastify = 'updated'
        next()
      })
    })

  fastify.get('/', function (request, reply) {
    // getOnlyFastify should change and getOnlyFastify should not
    console.log(request.getAndSetFastify) // updated
    console.log(request.getOnlyFastify) // original message

    reply.send({ hello: 'world' })
  })

Checklist