Controllers, Handlers, and Response Types
Handlers are the runtime's application-facing entrypoints. They should be easy to read, explicit about what they return, and small enough that the real business rules remain inside services rather than inside request plumbing. The platform does not need a large philosophical distinction between "controllers" and "handlers"; it needs predictable entrypoints and disciplined ownership.
Controllers are useful as organizational groupings for related handlers, but the handler contract is what matters. A handler should declare its inputs through typed extraction, call domain services for business work, perform capability checks where needed, and choose a response shape. It should not perform deep query construction, policy inference, and template assembly all in one place. That pattern recreates the worst characteristics of legacy MVC while hiding them behind nicer syntax.
The runtime should support several first-class response types. Full HTML pages are the default for public pages, account areas, and admin surfaces. HTML fragments are just as important because progressive enhancement depends on being able to update focused parts of a page without building a parallel JSON API for every interaction. Redirect responses remain central for form flows and post-redirect-get handling. Typed JSON responses exist for genuinely API-shaped use cases. File or stream responses are also necessary for some asset or export flows, but they should still pass through the same auth, tracing, and storage policy rules.
Typed extraction is a major part of the design. A handler should receive parsed route parameters, validated query inputs, structured form data, session context, principal context, and explicit service dependencies. This keeps request validation close to the edge and makes handlers easier to test. It also makes the platform friendlier to code generation and convention without requiring a magic service locator model.
Fragment responses deserve special emphasis. In this platform, HTML-over-the-wire is not a second-class workaround. Availability refreshes, admin table filters, validation rerenders, and component-level updates should use the same rendering engine, authorization checks, and cache policy model as full-page responses. A fragment is still a real response with explicit correctness and observability rules.
The platform should also encourage a clear separation between response shaping and side effects. If a handler needs to send mail, update search indexes, sync storage, or emit analytics, that work should usually happen through jobs or typed events rather than by expanding the handler until it becomes the de facto workflow engine. Thin handlers are not an aesthetic preference here; they are how the runtime keeps domain logic composable.