Skip to content

feat: respond 405 Method Not Allowed instead of 404 - #86

Merged
notrab merged 1 commit into
notrab:mainfrom
Ray-s-Forks:feat/method-not-allowed
Sep 12, 2026
Merged

notrab merged 1 commit into
notrab:mainfrom
Ray-s-Forks:feat/method-not-allowed

Conversation

@rayblair06

Copy link
Copy Markdown
Contributor

A request to a registered path with an unregistered method returned 404 Not Found. FastRoute reports METHOD_NOT_ALLOWED along with the methods that path accepts, but Router::findRoute() discarded that and returned null, which handle() could not tell apart from a genuinely missing route.

POST /users on a GET-only route now returns:

    HTTP/1.1 405 Method Not Allowed
    Allow: GET, POST

Unknown paths still return 404.

Changes

  • Router::dispatch() returns ['route' => array|null, 'allowedMethods' => string[]]. findRoute() is now a wrapper over it and keeps its existing contract, so nothing that calls it needs to change.
  • Dumbo::handle() returns a 405 with an Allow header when the path matched but the method did not. Like the 404, it runs through the middleware stack, so CORS and logging still apply.
  • HEAD is unaffected: FastRoute already falls back to the GET route, and there's a test covering it.

Behaviour change

This is the one thing worth a second opinion. Hono returns 404 for a method mismatch, so if you'd rather match Hono, I'm happy to close this. 405 with Allow is what RFC 9110 calls for, and what modern PHP frameworks like Slim and Laravel do.

Allow lists only the methods actually registered for the path. It does not add HEAD for GET routes, even though HEAD works via FastRoute's fallback. Happy to add that if you'd prefer.

Testing

  • 7 new tests (90 total):
    • Router::dispatch() for a method mismatch, an unknown path and a normal match
    • the 405 status and Allow header
    • unknown paths still 404, with no Allow header
    • HEAD still falls back to the GET route
    • middleware still runs for a 405
  • Checked end to end with php -S and curl.

@rayblair06
rayblair06 force-pushed the feat/method-not-allowed branch from 37cc2af to 022d9d9 Compare September 12, 2026 09:52
@notrab
notrab merged commit 65c0917 into notrab:main Sep 12, 2026
3 checks passed
@notrab

notrab commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Nice! 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants