Skip to content

Inconsistent behavior of /** syntax in TrieRouter vs other routers #4623

@NiebieskiRekin

Description

@NiebieskiRekin

What is the feature you are proposing?

Description

While /** is not explicitly documented as standard Hono syntax, it appears to be supported (or treated equivalently to /*) by RegExpRouter, PatternRouter, and LinearRouter.

However, TrieRouter (which SmartRouter defaults to in many cases) fails to match routes defined with /**, returning a 404. This creates a hidden pitfall where switching routers (or adding routes that cause SmartRouter to switch internal strategies) breaks existing route matching.

Code sample

The following code demonstrates that TrieRouter returns 404 for /auth/**, but changing the router to another one or the route to /* makes it work.

import { serve } from '@hono/node-server'
import { Hono } from 'hono'
import { getRouterName, showRoutes } from 'hono/dev';
import { PatternRouter } from 'hono/router/pattern-router';
import { LinearRouter } from 'hono/router/linear-router';
import { RegExpRouter } from 'hono/router/reg-exp-router';
import { TrieRouter } from 'hono/router/trie-router';

const app = new Hono({router: new TrieRouter()})
  .on(["POST", "GET"], "/auth/**", (c) => c.json({})) // Note **

showRoutes(app)

serve({
  fetch: app.fetch,
  port: 3001
}, (info) => {
  console.log(getRouterName(app));
  fetch(`http://localhost:${info.port}/auth/hello`).then(async (res)=>{
    if (res.ok){
      console.log("OK!")
    } else {
      console.error("Error! "+res.status)
    }
  }
  )
})

Output:

POST  /auth/**
GET   /auth/**
TrieRouter
Error! 404

After changing routers:

RegExpRouter

const app = new Hono({router: new RegExpRouter()})
  .on(["POST", "GET"], "/auth/**", (c) => c.json({}))

Output:

POST  /auth/**
GET   /auth/**
RegExpRouter
OK!

PatternRouter

const app = new Hono({router: new PatternRouter()})
  .on(["POST", "GET"], "/auth/**", (c) => c.json({}))

Output:

POST  /auth/**
GET   /auth/**
PatternRouter
OK!

LinearRouter

const app = new Hono({router: new LinearRouter()})
  .on(["POST", "GET"], "/auth/**", (c) => c.json({}))

Output:

POST  /auth/**
GET   /auth/**
LinearRouter
OK!

After changing the route to /*

const app = new Hono({router: new TrieRouter()})
  .on(["POST", "GET"], "/auth/*", (c) => c.json({})) // Note *

Output:

POST  /auth/*
GET   /auth/*
TrieRouter
OK!

Proposal

Behavior should be consistent across routers.

If /** is intended to be supported as an alias for /* (or a recursive wildcard), TrieRouter should support it.

If /** is invalid syntax, other routers should ideally not match it, or Hono should warn during route registration or in the docs.

Currently, it works in 3 out of 4 routers.

TrieRouter:    404 Not Found
RegExpRouter:  200 OK
PatternRouter: 200 OK
LinearRouter:  200 OK

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions