Skip to content
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

app.mount() removing the subpath from the request url is causing routing error in the inner routers #2781

Closed
G4brym opened this issue May 24, 2024 · 5 comments · Fixed by #2852
Labels

Comments

@G4brym
Copy link

G4brym commented May 24, 2024

What version of Hono are you using?

4.3.11

What runtime/platform is your app running on?

Cloudflare workers

What steps can reproduce the bug?

app.mount() removes the subpath, and this is causing some issues in the inner mounted router.
I think the current behavior works for almost all applications, and in my opinion it should continue to be the default behavior, but in some particular routers, like itty-router-openapi that auto generates some routes for users, is causing some routes to point to non-existing routes.

This issue was raised in itty-router-openapi repo here and the linked issue provides some more information on this.

This example uses itty-router-openapi, but it would work the same way in other routers

import { OpenAPIRouter } from '@cloudflare/itty-router-openapi'
import { Hono } from 'hono'

const router = OpenAPIRouter()
router.get('/example', (request) => new Response(request.url))

const app = new Hono()
app.mount('/api', router.handle)

export default app

What is the expected behavior?

Before this issue was raised in itty-router-openapi repository, i wasn't aware of this request.url change from Hono, so my expected behavior before knowing this, would be that a user would just define the base parameter in itty-router-openapi and everything would work correctly, like this example

import { OpenAPIRouter } from '@cloudflare/itty-router-openapi'
import { Hono } from 'hono'

const router = OpenAPIRouter({ base: '/api' })
router.get('/example', (request) => new Response(request.url))

const app = new Hono()
app.mount('/api', router.handle)

export default app

In this example, calling http://localhost:8787/api/example would print http://localhost:8787/api/example.

What do you see instead?

Running the script in the "What steps can reproduce the bug", then calling http://localhost:8787/api/example prints http://localhost:8787/example.

An example of the auto generated routes not working is to open this url http://localhost:8787/api/docs in the browser, that is trowing an error, because the lib expects the openapi spec to be an /openapi.json but it actually is in /api/openapi.json because of the url re-write.

Additional information

I think that this should continue to be the default way of mounting other routers in Hono, as probably some routers don't support defining base paths and makes the developer experience better for users.

My initial suggestion was to add a parameter when calling the inner router in this line, and this would make "it work" for users, and users wouldn't need to change anything, then on itty-router-openapi side I could expect this new parameter and work around it.
But after talking to @yusukebe he suggested creating an additional option to disable this behavior, maybe something like this app.mount('/api', router.handle, { subpathRewrite: false })

@G4brym G4brym added the bug label May 24, 2024
@yusukebe
Copy link
Member

Hi @G4brym

Thank you for creating the issue. I'll comment on it later!

@G4brym
Copy link
Author

G4brym commented Jun 3, 2024

Thanks for the quick fix ♥️

@yusukebe
Copy link
Member

yusukebe commented Jun 3, 2024

@G4brym It's my pleasure! Try it and let me know if it's not resolved.

@yusukebe
Copy link
Member

yusukebe commented Jun 3, 2024

@G4brym

I did'nt tell you the usage. Here is example you may want to do:

import { Hono } from 'hono'
import { AutoRouter } from 'itty-router'

const ittyRouter = AutoRouter()

ittyRouter.get('*', ({ url }) => `${url}`)

const app = new Hono()

app.mount('/itty', ittyRouter.fetch, {
  replaceRequest: (req) => req,
})

export default app

@G4brym
Copy link
Author

G4brym commented Jun 5, 2024

@yusukebe
I've just tested it now and works as expected
Thanks 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants