[PR #968] [MERGED] refactor: Extract app route handler dispatch #989

Closed
opened 2026-05-06 13:11:24 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/968
Author: @NathanDrake2406
Created: 4/29/2026
Status: Merged
Merged: 4/29/2026
Merged by: @james-elicx

Base: mainHead: nathan/extract-route-handler-dispatch


📝 Commits (1)

  • ecd7f7a refactor: extract app route handler dispatch

📊 Changes

5 files changed (+672 additions, -1103 deletions)

View changed files

📝 packages/vinext/src/entries/app-rsc-entry.ts (+27 -171)
packages/vinext/src/server/app-route-handler-dispatch.ts (+264 -0)
📝 tests/__snapshots__/entry-templates.test.ts.snap (+150 -918)
tests/app-route-handler-dispatch.test.ts (+218 -0)
📝 tests/app-router.test.ts (+13 -14)

📄 Description

What changed

This extracts App Router route.ts dispatch out of the generated RSC entry and into a normal typed runtime module: server/app-route-handler-dispatch.ts.

The generated entry now describes only the app shape and request seams for a matched route handler:

  • route pattern, route handler module, and route segments
  • request, params, search params, i18n/base path
  • ISR storage hooks and request-context cleanup
  • middleware response context

The new dispatcher owns the behavior previously embedded in codegen:

  • default-export warning in dev
  • HTTP method resolution, auto-HEAD, auto-OPTIONS, and 405 responses
  • route handler ISR read path and stale regeneration context
  • user handler execution, response finalization, middleware merge, and cache writes through the existing helper modules

Why

Generated entries should describe the application shape. Normal modules should implement behavior. The old route.ts branch in entries/app-rsc-entry.ts was still making runtime decisions even though the lower-level policy/cache/execution helpers already existed.

This mirrors the shape of Next.js more closely: the build template creates a route module, and the route module owns request handling behavior.

Relevant Next.js references:

Tests

  • vp check packages/vinext/src/server/app-route-handler-dispatch.ts packages/vinext/src/entries/app-rsc-entry.ts tests/app-route-handler-dispatch.test.ts tests/app-router.test.ts tests/__snapshots__/entry-templates.test.ts.snap
  • vp test run tests/app-route-handler-dispatch.test.ts tests/app-route-handler-execution.test.ts tests/app-route-handler-cache.test.ts tests/app-route-handler-policy.test.ts tests/app-route-handler-response.test.ts tests/app-router.test.ts tests/nextjs-compat/app-routes.test.ts tests/entry-templates.test.ts -t "app route handler dispatch|app route handler|APP_ROUTE ISR|route handler|Route Handlers|Basic HTTP methods|HEAD|OPTIONS|unimplemented method|route handler ISR|catch-all route handler|dev mode|App Router RSC entry template"
  • vp test run tests/entry-templates.test.ts
  • vp run vinext#build

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/968 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 4/29/2026 **Status:** ✅ Merged **Merged:** 4/29/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `nathan/extract-route-handler-dispatch` --- ### 📝 Commits (1) - [`ecd7f7a`](https://github.com/cloudflare/vinext/commit/ecd7f7ab9835898fdbc71ace9bb39a54b9ec550e) refactor: extract app route handler dispatch ### 📊 Changes **5 files changed** (+672 additions, -1103 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/entries/app-rsc-entry.ts` (+27 -171) ➕ `packages/vinext/src/server/app-route-handler-dispatch.ts` (+264 -0) 📝 `tests/__snapshots__/entry-templates.test.ts.snap` (+150 -918) ➕ `tests/app-route-handler-dispatch.test.ts` (+218 -0) 📝 `tests/app-router.test.ts` (+13 -14) </details> ### 📄 Description ## What changed This extracts App Router `route.ts` dispatch out of the generated RSC entry and into a normal typed runtime module: `server/app-route-handler-dispatch.ts`. The generated entry now describes only the app shape and request seams for a matched route handler: - route pattern, route handler module, and route segments - request, params, search params, i18n/base path - ISR storage hooks and request-context cleanup - middleware response context The new dispatcher owns the behavior previously embedded in codegen: - default-export warning in dev - HTTP method resolution, auto-`HEAD`, auto-`OPTIONS`, and 405 responses - route handler ISR read path and stale regeneration context - user handler execution, response finalization, middleware merge, and cache writes through the existing helper modules ## Why Generated entries should describe the application shape. Normal modules should implement behavior. The old `route.ts` branch in `entries/app-rsc-entry.ts` was still making runtime decisions even though the lower-level policy/cache/execution helpers already existed. This mirrors the shape of Next.js more closely: the build template creates a route module, and the route module owns request handling behavior. Relevant Next.js references: - [`app-route` build template creates `AppRouteRouteModule`](https://github.com/vercel/next.js/blob/e1bb911c14e4ea3c6bb8cc98871ffdee317d513f/packages/next/src/build/templates/app-route.ts#L48-L80) - [`AppRouteRouteModule` initializes userland methods and route config](https://github.com/vercel/next.js/blob/e1bb911c14e4ea3c6bb8cc98871ffdee317d513f/packages/next/src/server/route-modules/app-route/module.ts#L325-L337) - [`AppRouteRouteModule.handle()` owns request dispatch and response validation](https://github.com/vercel/next.js/blob/e1bb911c14e4ea3c6bb8cc98871ffdee317d513f/packages/next/src/server/route-modules/app-route/module.ts#L798-L981) - [`autoImplementMethods()` owns auto-`HEAD`, auto-`OPTIONS`, and 405 defaults](https://github.com/vercel/next.js/blob/e1bb911c14e4ea3c6bb8cc98871ffdee317d513f/packages/next/src/server/route-modules/app-route/helpers/auto-implement-methods.ts#L11-L81) ## Tests - `vp check packages/vinext/src/server/app-route-handler-dispatch.ts packages/vinext/src/entries/app-rsc-entry.ts tests/app-route-handler-dispatch.test.ts tests/app-router.test.ts tests/__snapshots__/entry-templates.test.ts.snap` - `vp test run tests/app-route-handler-dispatch.test.ts tests/app-route-handler-execution.test.ts tests/app-route-handler-cache.test.ts tests/app-route-handler-policy.test.ts tests/app-route-handler-response.test.ts tests/app-router.test.ts tests/nextjs-compat/app-routes.test.ts tests/entry-templates.test.ts -t "app route handler dispatch|app route handler|APP_ROUTE ISR|route handler|Route Handlers|Basic HTTP methods|HEAD|OPTIONS|unimplemented method|route handler ISR|catch-all route handler|dev mode|App Router RSC entry template"` - `vp test run tests/entry-templates.test.ts` - `vp run vinext#build` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:11:24 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#989
No description provided.