Comments (9)
TL;DR - there is no elegant solution to monkeypatching.
Unfortunately much of the express ecosystem relies on monkey patching the end()
method. This is one of the key technical differences between the two frameworks, and partially one of the reasons why @delvedor and myself started Fastify long ago.
In essence this issue is out of scope. As you said, this behavior is explicitly called in the README because we did not want to get into the monkey patching Express (that monkey patches node core), as it's going to be messy and it won't work for all applications so it would need to stay behind an option, disabled by default. The good thing is that I think it's doable.
from fastify-express.
Unfortunately much of the express ecosystem relies on monkey patching the
end()
method. This is one of the key technical differences between the two frameworks, and partially one of the reasons why @delvedor and myself started Fastify long ago.
💯
I think it's a way better approach in general and am looking forward to completing migration. We just need to be able to migrate an app running in production piece by piece in between other product development, so packages such as this is awesome 😀 Happy to accept hacks as they are (in theory) temporary
The good thing is that I think it's doable.
Happy to take a stab at a PR if you can provide some guidance on where/how to approach this 🙂
from fastify-express.
The quickest way is probably to lift https://github.com/SerayaEryn/fastify-session/blob/e201f78fc9d7bd33c6f2e84988be7c8af4b5a8a3/lib/fastifySession.js#L93-L113 and do the monkey patching express-session
does before fastify-express is set up. You might also have to fork fastify-express to do this - as I said it's not going to be nice.
We might also add an option function that will be called to do these kind of monkey-patching manually.
from fastify-express.
Thanks! So just to verify I've understood correctly
- Before registering
express-fastify
, add the code fromexpress-session
which monkeypatchesres.end
so that I can override it and add a hook to do something:tm: before response is sent to the client - This might require some changes in
fastify-express
as well, that is as of now unclear - Make sure to call
onSend
fromfastify-session
within the hook added in step 1
Does that seem right? And 1&2 might be accepted as PRs to this repo behind an option
from fastify-express.
Yes exactly regarding the PRs. I would not make the new code/options specific to express-session, but make it pluggable (by calling a user-provided function).
from fastify-express.
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.
from fastify-express.
I've been swamped for the last few months. I do plan to get back to this some time in the summer
from fastify-express.
The following information may dissuade you from completing this task. There are other issues at play when mixing native Fastify and non-native Express routes in the same app. My recommendation is to create a brand new repo/app for your migration and not mix native/non-native routes because of many moving variables at play.
I was trying to migrate an existing Express app putting the old and new routes into the same app. I'm sorry to report that the "monkeypatching" may be at play here too. There are two bad scenarios:
- When an Express 404 handler is present, all valid, native Fastify routes are incorrectly caught by it resulting in 404.
- When the Express 404 handler is removed all non-existent routes are correctly caught by the Fastify OOTB 404 handler and GET routes seem to work as shown in the OP. Unfortunately, with the PATCH route and Express body parsers active in the example below, the request just hangs because of the Express body parsers. I did find an interesting outcome, when I comment out the Express body parsers and when a native Fastify route co-exists, the req.body is parsed by the Fastify OOTB parser making req.body available without an Express body parser. Your two working scenarios are then:
- No Express body parsers but at least one native Fastify route and no Express 404 handler. The req.body is parsed by the Fastify OOTB parser automatically.
- No native Fastify routes but with Express body parsers. If you need an Express 404 handler, you can use it or else it defaults to the Fastify OOTB 404 handler.
const fastify = require('fastify')()
const express = require('express')
const router = express.Router()
// non-Express, native route. Caught by 404 hander if it exists, or hangs if 404 handler doesn't exist.
fastify.patch('/bar-fastify', handlePatch)
fastify.get('/hello-fastify', handleGet)
// Express routes
router.use(function (req, res, next) {
res.setHeader('x-custom', true)
next()
})
router.get('/hello', handleGet)
router.get('/foo', (req, res) => {
res.status(400)
res.json({ foo: 'bar' })
})
router.patch('/bar', handlePatch)
// Express 404 handler. When present, fastify routes incorrectly get 404. When commented out, GET works but PATCH hangs.
// router.use('*', (req, res) => {
// res.status(404)
// res.json({ msg: 'not found'})
// })
fastify.register(require('fastify-express'))
.after(() => {
// These need to be removed if you have a native Fastify route or parsing hangs
// fastify.use(express.urlencoded({extended: false})) // for Postman x-www-form-urlencoded
// fastify.use(express.json())
fastify.use(router)
})
fastify.listen(3000, console.log)
async function handlePatch (req, res) {
if (!req.body || Object.keys(req.body).length === 0) {
res.status(400)
const output = { msg: 'no req.body'}
res.json ? res.json(output) : res.send(output)
} else {
res.status(200)
res.json ? res.json(req.body) : res.send(req.body)
}
}
async function handleGet (req, res) {
res.status(201)
const output = { hello: 'world' }
res.json ? res.json(output) : res.send(output)
}
My curl commands:
me@computer ~ % curl -X GET http://localhost:3000/asdf (CORRECT with Fastify OOTB 404 handler)
{"message":"Route GET:/asdf not found","error":"Not Found","statusCode":404}
me@computer ~ % curl -X GET http://localhost:3000/asdf (CORRECT with Express 404 handler)
{"msg":"not found"}
me@computer ~ % curl -X GET http://localhost:3000/hello (CORRECT)
{"hello":"world"}
me@computer ~ % curl -X GET http://localhost:3000/hello-fastify (INCORRECT with Express 404 handler)
{"msg":"not found"}
me@computer ~ % curl -X GET http://localhost:3000/hello-fastify (CORRECT w/o Express 404 handler)
{"hello":"world"}
me@computer ~ % curl -X PATCH -H 'content-type:application/json' -d '{"foo2":"bar2"}' http://localhost:3000/bar-fastify (HANGS w/o Express 404 handler and with Express body parser and with Fastify native route)
^C
me@computer ~ % curl -X PATCH -H 'content-type:application/json' -d '{"foo2":"bar2"}' http://localhost:3000/bar-fastify (INCORRECT with Express 404 handler)
{"msg":"not found"}
me@computer ~ % curl -X PATCH -H 'content-type:application/json' -d '{"foo2":"bar2"}' http://localhost:3000/bar-fastify (CORRECT w/o Express 404 handler and w/o Express body parsers and with Fastify native route)
{"foo2":"bar2"}
from fastify-express.
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.
from fastify-express.
Related Issues (20)
- @fastify-express not working inside a plugin HOT 3
- `request.url` is mutated between `onRequest` and `onResponse` HOT 8
- Express wildcard routes override Fastify routes
- Swagger MIME type ('application/json') is not a supported stylesheet MIME type HOT 1
- 👋 I'm Cris, and would like to work on this. HOT 1
- 👋 I'm Cris, and would like to work on this. HOT 2
- Headers set by fastify are ignored if `express` handles request HOT 4
- Issue v5 release
- Express routes don't work when an Express router is added inside a plugin HOT 11
- FST_ERR_DEC_ALREADY_PRESENT when register fastify-express HOT 2
- Headers are `null` when using `.inject` HOT 14
- `fastify` should be added as a dep to `package.json` HOT 2
- When testing express application with inject, payload is always empty HOT 3
- Document that HTTP/2 is not supported when using fastify-express HOT 2
- FastifyError when using fastify-express with Nest.js and Fastify HOT 3
- Unable to get plugin working with typescript + require HOT 2
- Express middleware cannot access request.body HOT 7
- TypeScript declarations specify non-existent named export HOT 1
- Why the `expressHook` should be `preHandler` and not `preValidation`? HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fastify-express.