-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MiddlewareConsumer routing is broken #8108
Comments
Please provide a minimum reproduction repository. |
@jmcdo29 https://github.com/oleg-yudovich/nestjs_8_routing_bug |
Wouldn't this be due to how regex matches work? i.e. if you want to hit just |
@jmcdo29 I don't think you're right. If I register two routes, let's say
|
http://127.0.0.1:3001/test => hit path / const express = require('express')
const app = express()
app.use('/', function (req, res, next) {
if (req.url === '/') {
console.log('isRequestMapping')
}
if (req.method === 'GET') {
res.send('hit path /')
}
})
app.use('/test', function (req, res, next) {
if (req.url === '/') {
console.log('isRequestMapping')
}
if (req.method === 'GET') {
res.send('hit path test')
}
})
app.listen(3001) http://127.0.0.1:3001/test => hit path /test const express = require('express')
const app = express()
app.use('/test', function (req, res, next) {
if (req.url === '/') {
console.log('isRequestMapping')
}
if (req.method === 'GET') {
res.send('hit path test')
}
})
app.use('/', function (req, res, next) {
if (req.url === '/') {
console.log('isRequestMapping')
}
if (req.method === 'GET') {
res.send('hit path /')
}
})
app.listen(3001) the bug description: Current behavior forRoutes({ path: '/' }, { path: '/test/app' }, { path: '/:username' }) === forRoutes(AppController) Expected behavior forRoutes(AppController) should be equal to [{ path: '/$' }, { path: '/test/app$' }, { path: '/:username$' }] forRoutes({ path: '/' }, { path: '/test/app' }, { path: '/:username' }) should be not equal to forRoutes(AppController) |
app.use != app.get post ... |
@Zclhlmgqzc @kamilmysliwiec FYI - this patch does not solve the problem. Please see the example in this simple repo. |
forRoutes(AppController) should be equal to [{ path: '/$' }, { path: '/test/app$' }, { path: '/:username$' }] forRoutes({ path: '/' }, { path: '/test/app' }, { path: '/:username' }) should be not equal to forRoutes(AppController) so use /$ instead of / app.use(/) != app.use(/$) |
So is not really a fix to the issue. Now we have different behavior of controllers routing and middleware consumer routing. Is still a bug IMHO |
Do we understand why this issue started in NestJS 8 in the first place? |
I think it's a break change instead of bug nest forRoutes(path /) === express use(/) forRoutes(Controller) === forRoutes(path /$) === express use(/$) ≈≈ express.all(/) |
To avoid introducing a breaking change, we might need to revert all middleware-specific PRs (all changes since 8.0.5) and wait with that till we release v9 unless you have a better idea @Zclhlmgqzc |
but some breaking change in router-method-factory forRoutes(7.x path / != 8.x path /) 7.6.18-router-method-factory 7.x forRoutes('/xx') === 8.0.4 forRoutes(/xx GET) === 8.0.10 forRoutes(/xx$ GET) 7.x forRoutes('/xx') != 8.x forRoutes('/xx') 7.x forRoutes(/xx ALL) === 8.0.4/8.0.10 forRoutes('/xx') |
@kamilmysliwiec see #7759 maybe it can fix this problem
|
@kamilmysliwiec @Zclhlmgqzc I found the bug is bigger than described. Actually routing engine through MiddlewareConsumer is completely broken. When you define:
The |
try nest-8.0.0/8.0.10: // RouterMethodFactory default: return target.use
// In this case the /test/about will never be reached also
export class RoutingModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply((req, res) => res.send('hit path /test'))
.forRoutes('/test')
.apply((req, res) => res.send('hit path /test/about'))
.forRoutes('/test/about');
}
} nest-7.x: // RouterMethodFactory case RequestMethod.ALL: return target.use
// In this case the /test/about will never be reached also
export class RoutingModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply((req, res) => res.send('hit path /test'))
.forRoutes({ path: '/test', method: RequestMethod.ALL })
.apply((req, res) => res.send('hit path /test/about'))
.forRoutes({ path: '/test/about', method: RequestMethod.ALL });
}
} Express middleware .use and .all/get/post/delete/put (Router-level middleware) in #8230 @Controller()
export class AppController {
@All('/xx')
homepage(): string {
return 'hit /';
}
}
forRoutes('/xx') === forRoutes(AppController) === forRoutes({ path: '/xx', isRequestMapping: true }) ≈≈ express.all('/xx')
forRoutes({ path: '/xx', isRequestMapping: false }) === express.use('/xx') |
@oleg-yudovich this is how fastify/express middleware works. This is not a bug & nor it's "completely broken".
@Zclhlmgqzc this PR won't fix this issue. To move back to the behavior before 8.0.5, we must revert these PRs you've made:
and save them for v9. Would you like to create a revert PR (reverting all changes that were made in the PRs above) and then a PR combining those two so we can have them prepared for v9? UPDATE:
@Zclhlmgqzc can you revert this PR #7562 then? We can then create a separate PR |
@kamilmysliwiec in NestJS 7 What is the proper way of calling express |
@kamilmysliwiec If must be revert #7562 + public createMiddlewareFactory(
+ requestMethod: RequestMethod,
+ ): (path: string, callback: Function) => any {
+ return this.routerMethodFactory
+ .get(this.instance, requestMethod)
+ .bind(this.instance);
- public createMiddlewareFactory(): (path: string, callback: Function) => any {
- return this.instance.use.bind(this.instance);
- } |
We want to get back to the behavior before v8.0.5 to avoid introducing breaking changes. (using We can save all improvements you made till v9 |
but if some one else use forRoutes('/xxx') in nest-8 it will use use()
|
We might need to revert this back to |
This should be fixed in 8.0.11 |
Thanks, @kamilmysliwiec, and @Zclhlmgqzc . |
Bug Report
Current behavior
The
MiddlewareConsumer
routing is broken when you define home route:/
All routes mapped to the same path '/'
Input Code
Routing module:
App module:
Get request to the '/test/app' and '/:username' prints 'hit path /'
Feels like '/' defined as '*'
Expected behavior
The
/test/app
and/:username
routes should be accessiblePossible Solution
Environment
The text was updated successfully, but these errors were encountered: