# A3S Boot Nest Parity Roadmap
This roadmap tracks the work needed to move `a3s-boot` from a Nest-inspired
HTTP framework slice toward a fuller Rust equivalent of the high-value Nest.js
developer experience.
The goal is not to copy TypeScript runtime reflection. A3S Boot should keep
Rust's explicit types, compile-time macros, adapter-neutral core, and small
runtime surface. Nest parity means preserving the workflows users expect:
module boundaries, injectable services, declarative controllers, request
pipelines, generated API documentation, and transport integrations.
Official Nest.js areas used as reference:
- Modules: https://docs.nestjs.com/modules
- Lifecycle events: https://docs.nestjs.com/fundamentals/lifecycle-events
- Providers: https://docs.nestjs.com/providers
- Controllers: https://docs.nestjs.com/controllers
- Middleware: https://docs.nestjs.com/middleware
- Pipes and validation: https://docs.nestjs.com/pipes and https://docs.nestjs.com/techniques/validation
- Guards, interceptors, filters: https://docs.nestjs.com/guards, https://docs.nestjs.com/interceptors, https://docs.nestjs.com/exception-filters
- OpenAPI: https://docs.nestjs.com/openapi/introduction
- WebSockets: https://docs.nestjs.com/websockets/gateways
- Microservices: https://docs.nestjs.com/microservices/basics
- Techniques: https://docs.nestjs.com/techniques/configuration
## Current Baseline
Implemented today:
- `Module` with imports, providers, controllers, direct routes, module route
prefixes, and lifecycle hooks.
- `BootFactory` with NestFactory-style `create`, `create_application_context`,
`create_microservice`, async provider-aware `create_async`,
`create_application_context_async`, and `create_microservice_async`, managed
`init`/`close`, signal-aware shutdown helpers, Nest-style
`enable_shutdown_hooks`, `listen_with`, and hybrid microservice startup
helpers.
- `ProviderDefinition` and `ModuleRef` for typed provider registration,
singleton/request/transient lifecycle scopes, async singleton provider
factories, singleton provider lifecycle hooks, lookup, `FromModuleRef`
auto-wired provider factories, named or optional dependency resolution,
`ProviderRef<T>` lazy provider handles for forward-reference-style
dependencies, declared eager dependency graphs with automatic request-scope
propagation, public `ContextId` / `ContextIdFactory` identities, fresh or
caller-shared resolution contexts, per-inquirer transient reuse, and dynamic
injectable creation.
- DI-managed application-wide enhancers corresponding to Nest's `APP_GUARD`,
`APP_PIPE`, `APP_INTERCEPTOR`, and `APP_FILTER`, with typed provider markers
for HTTP plus protocol-specific WebSocket and transport variants, automatic
scope bubbling, and per-invocation contextual resolution.
- `TestingModule` with module and provider overrides, async provider-aware
`compile_async`, and typed HTTP, WebSocket, and transport pipeline overrides
for guards, interceptors, exception filters, and pipes, including
provider-backed application enhancers.
- `ControllerDefinition` and `RouteDefinition` for HTTP route groups, including
specificity-aware path params, catch-all route params, and Nest-style ALL
method routes with exact-method precedence.
- Nest-style attribute macros: `#[module]`, `#[injectable]`, `#[controller]`,
`#[all]`, `#[get]`, `#[post]`, `#[put]`, `#[patch]`, `#[delete]`, `#[sse]`,
raw route mode, and method argument extractors including `#[body]`,
`#[body("name")]`, `#[request]`, `#[param("name")]`, `#[params]`, `#[query]`,
`#[query("name")]`, `#[header("name")]`, `#[headers]`, `#[cookie("name")]`,
`#[cookies]`, `#[host_param("name")]`, `#[ip]`, and custom `#[extract(...)]`
request value binding. Single-value extractors can also run Nest-style
parameter pipes through `pipe = <expr>`, for example
`#[param("id", pipe = parse_cat_id)]`, `#[query("page", pipe = parse_page)]`,
and `#[body("page", pipe = ParseIntPipe)]`, plus `#[host]` for
host-scoped controllers and routes, `#[metadata]` for
Nest-style custom route/controller metadata and `#[http_code]` for Nest-style
response status metadata, `#[cache_key]` / `#[cache_ttl]` for cache response
metadata, `#[header]` for response headers, and `#[redirect]` for redirect
responses. `#[injectable]` implements `FromModuleRef` and dependency metadata
for unit structs and named-field structs whose dependencies are `Arc<T>`,
`Option<Arc<T>>`, `ProviderRef<T>`, or `Option<ProviderRef<T>>`, with
`#[inject("token")]` for named provider lookup.
`#[module]` implements `Module` from Nest-style metadata lists for imports,
providers, controllers, routes, gateways, message controllers, exports,
route prefixes, and global modules.
- Nest-style OpenAPI security macros: `#[bearer_auth]`, `#[api_security]`,
`#[api_cookie_auth]`, and `#[api_key_auth]`, including operation security
requirements and generated security schemes for bearer, cookie, header, and
query API key authentication.
- Nest-style decorator composition with `#[apply_decorators(...)]` for
grouping HTTP controller/route, WebSocket gateway/subscription, and message
controller/pattern attributes such as routing, metadata, pipeline hooks,
validation, versioning, response metadata, and OpenAPI decorators.
- WebSocket lifecycle macros: `#[on_gateway_init]`,
`#[on_gateway_connection]`, and `#[on_gateway_disconnect]`.
- Host-scoped HTTP routes with `RouteDefinition::with_host(...)` and
`ControllerDefinition::with_host(...)` for Nest-style host-based controllers.
- API versioning macros: `#[version]`, `#[versions]`, and
`#[version_neutral]` at controller and route scope.
- Serialization macros with `#[serialize(include = [...], exclude = [...],
skip_null)]` at controller and route scope.
- Nest-style generic pipeline macros: `#[use_guard]`, `#[use_interceptor]`,
`#[use_filter]`, and `#[use_pipe]` at HTTP controller/route,
WebSocket gateway/subscription, and message controller/pattern scope.
- A shared Nest-style `CallHandler` abstraction for the protocol-specific HTTP,
WebSocket, and message-transport around-interceptor traits. Interceptors can transform or
recover downstream errors, short-circuit without calling `next`, and apply
sequential retries or runtime-specific timeouts around reusable
`next.handle()` calls. Existing
`before` / `short_circuit` / `after` implementations remain compatible
through the default `intercept(...)` methods, and exception filters receive
only errors that remain unrecovered after the interceptor chain.
- Nest-style catch-filter targeting with `#[catch]`, `BootErrorKind`,
`catch_errors(...)`, `with_catch_filter(...)`, and
`use_global_catch_filter(...)`, plus protocol-specific global WebSocket and
transport pipes and catch filters.
- Nest-style HTTP exception helpers with typed `BootError` constructors for
common HTTP errors plus a generic `http_exception(status, message)` helper
comparable to Nest's `HttpException`.
- Nest-style default JSON error responses from `BootResponse::from_error(...)`,
application `handle(...)`, route `handle(...)`, and Axum fallback errors.
- Nest-style built-in request value pipes with `ParseIntPipe`, `ParseBoolPipe`,
`ParseFloatPipe`, `ParseArrayPipe`, `ParseEnumPipe`, `ParseUuidPipe`,
`DefaultValuePipe`, and extractor-level `default = ...` fallbacks.
- JSON body and JSON response helpers.
- SSE responses with `SseEvent`, `SseStream`, `BootResponse::sse(...)`,
`RouteDefinition::sse(...)`, `ControllerDefinition::sse(...)`, and Axum
streaming support.
- Nest-style streamable file and download responses with `StreamableFile`,
`StreamableFileOptions`, `BootResponse::streamable_file(...)`,
`BootResponse::download(...)`, byte-stream support, content disposition, and
Axum streaming support.
- Nest-style MVC view rendering with `ViewEngine`, `ViewRenderer`,
`ViewModule`, `StringTemplateViewEngine`, `RouteDefinition::get_view(...)`,
`ControllerDefinition::get_view(...)`, `BootResponse::html(...)`, and the
`#[render("view")]` route macro.
- Global, module, controller-level, and route-level middleware plus Nest-style
`MiddlewareConsumer` include/exclude route configuration, with global and
controller-level `Pipe`, `Guard`, `Interceptor`, and `ExceptionFilter`
support.
- Adapter-neutral request/response types, typed params/query helpers, typed
single-value parsing helpers, header helpers, cookie helpers, route matching,
global prefixes with Nest-style HTTP route exclusions, lifecycle hooks, and an
Axum adapter.
- OpenAPI route metadata, schema-crate-neutral document generation from resolved
routes, explicit Nest-style parameter decorators, automatic path-parameter
documentation, request/response examples, non-JSON media type metadata, and
security requirements plus generated `components.securitySchemes`, and
optional `serve_openapi(...)` JSON route registration plus
`serve_openapi_ui(...)` Swagger UI route registration.
- Custom route/controller, WebSocket gateway/subscription, and message
controller/pattern metadata through builders and `#[metadata]`, handler-level
override semantics, protocol-neutral `ExecutionContext` access for HTTP,
WebSocket, and transport guards/interceptors, and typed `Reflector` lookup
from discovery snapshots.
- Nest-style response passthrough with `ResponsePassthrough` and `#[res]`,
allowing controller methods to set status codes, headers, and cookies while
still returning a typed DTO or adapter-neutral `BootResponse`.
- Nest-style request cookie binding with typed `BootRequest` cookie helpers,
`#[cookie("name")]`, `#[cookies]`, pipe/default support for one cookie value,
and OpenAPI cookie parameter metadata.
- Nest-style JSON body field binding with typed `BootRequest` body field helpers,
`#[body("name")]`, pipe/default support for one body field value, and
automatic OpenAPI JSON object request-body metadata.
- Nest-style runtime discovery and devtools-ready application graph snapshots
for modules, imports, provider tokens, exports, route counts, WebSocket
gateway counts, and microservice message pattern counts.
- Optional task-local request context with `RequestContext`, request id,
path/param/query/header/metadata access, pipeline-local values, and auth
principal propagation when authentication is enabled.
- DTO validation with `Validate`, body/query/params validation hooks, global,
controller-level, route-level validation switches, Nest-style transform,
whitelist, and forbid-non-whitelisted options through `ValidationOptions` and
`ValidationSchema`, `ValidationSchema` derive support for named DTO structs,
global/controller/route validation options, and `#[validate]` /
`#[skip_validation]` macros including `#[validate(transform)]`,
`#[validate(whitelist)]`, and `#[validate(forbidNonWhitelisted)]`.
- Module-scoped provider registries, explicit provider exports, transitive
re-exports, global module exports, module route prefixes, and `DynamicModule`
for runtime-built provider modules, with provider-only lazy module loading,
module-level forward imports for deliberate circular module relationships,
and contextual module import cycle diagnostics.
- Provider lifecycle scopes with default singleton providers, request-scoped
providers cached per `ContextId`, transient providers reused per inquirer
within a context, async singleton provider factories awaited during async
graph build, automatic request-scope propagation through declared eager
dependency graphs, order-independent singleton provider graph initialization,
request-time lookup and automatic context identity through `BootRequest`,
singleton/transient/request-scoped provider dependency cycle diagnostics, and
singleton provider startup/shutdown hooks for module init, application
bootstrap, module destroy, before application shutdown, and application
shutdown, including OS signal labels from shutdown hooks.
- Provider aliases that mirror Nest custom provider `useExisting` semantics and
preserve target provider scope.
- Lazy `ProviderRef<T>` handles that mirror the useful part of Nest
`forwardRef(...)`: explicit delayed provider resolution without weakening
normal cycle diagnostics. Lazy edges intentionally do not propagate request
scope; callers use a captured request context or explicit `resolve(...)`.
- Module-level forward imports that mirror Nest `forwardRef(() => Module)` for
explicit circular module relationships while preserving normal import-cycle
diagnostics.
- Request-scoped route/controller handler factories through `*_scoped` helpers,
plus provider-backed macro controllers selected automatically for request,
transient, and dependency-bubbled controller graphs.
- Middleware with request mutation, short-circuit responses, global/module/
controller/route scopes, `MiddlewareConsumer::apply(...).for_routes(...)`
include/exclude rules, filter integration for errors, and adapter validation
before middleware execution.
- WebSocket gateways with adapter-neutral messages and connections, gateway
init/connection/disconnect lifecycle hooks, gateway- and subscription-scoped
pipes/guards/interceptors, application-wide protocol guards/interceptors/
pipes, local and global protocol exception filters, typed and validated
subscription message-body DTOs, provider-backed handlers, logical namespaces,
connection rooms, direct
emits, room or gateway-wide broadcasts, Nest-style gateway macros, and Axum
WebSocket route registration.
- Microservice transports with adapter-neutral `TransportMessage` /
`TransportReply`, request-response and event-only message patterns,
per-dispatch scoped handlers and message controllers, validation helpers,
transport pipes/guards/interceptors, application-wide protocol
guards/interceptors/pipes, local and global protocol exception filters,
Nest-style message macros with controller- and pattern-scoped pipeline
decorators, an in-process transport, and an optional
TCP transport for newline-delimited JSON message frames plus an optional Redis
Pub/Sub transport and optional NATS request/reply and event subjects plus
optional MQTT request/reply and event topics plus optional RabbitMQ
request/reply and event queues plus optional Kafka request/reply and event
topics plus optional gRPC unary request/reply and event calls. Transport error
envelopes round-trip through the same `BootError` HTTP exception mapping used
by HTTP routes.
- Optional native Tencent Weixin iLink support with an injectable client,
QR-login and redirect handling, authenticated update polling, text replies,
typing calls, lifecycle notifications, bounded responses, and strict URL
validation. Browser APIs, credential storage, and product authorization
remain host-application responsibilities.
- ACL-backed typed configuration modules with `ConfigModule`, named/global
provider exports, environment/default function support, and validation hooks.
- Provider-backed outbound HTTP clients with `HttpModule`, `HttpService`,
typed request/response helpers, base URL/default header/timeout options,
named/global exports, async option factories, and replaceable backends.
- Optional CQRS buses with `CqrsModule`, typed `CommandBus`, `QueryBus`, and
`EventBus`, module-scoped provider resolution through `CqrsContext`, duplicate
command/query handler diagnostics, and multi-handler event publishing.
- Optional provider-backed authentication with `AuthModule`, `AuthService`,
bearer or custom strategies, `AuthGuard`, route/controller auth metadata,
roles/scopes checks, public-route bypass, and `BootRequest` principals.
- Optional provider-backed database facade with `DatabaseModule`, `Database`,
backend and transaction traits, adapter-neutral statements/rows/results,
named/global provider exports, and an in-memory backend for tests.
- Typed cache modules with `CacheModule`, `Cache`, in-memory storage,
default TTLs, named/global provider exports, cache-store abstraction, and
Nest-style HTTP response caching through `CacheInterceptor`, `#[cache_key]`,
and `#[cache_ttl]`.
- Provider-backed task scheduling with `ScheduleModule`, `Scheduler`,
in-process timeout/interval/cron jobs, named/global provider exports,
Nest-style `#[schedule]` / `#[cron]` / `#[interval]` / `#[timeout]` macros,
and lifecycle-managed shutdown.
- Provider-backed queues with `QueueModule`, `Queue`, `a3s-lane` backed job
storage and workers, typed serde JSON payloads, named/global provider
exports, and lifecycle-managed processors.
- Provider-backed application events with `EventModule`, Nest-style
`EventEmitter`, injectable `a3s-event` `EventBus`, listener macros, and
pluggable providers.
- Provider-backed structured logging with `LoggingModule`, `Logger`, pluggable
sinks, in-memory test capture, request middleware/interceptor helpers, and
worker-friendly injection through the same provider graph.
- API versioning with URI, header, and media type strategies; route-level and
controller-level version metadata; default versions; and version-neutral
routes.
- JSON response serialization with `SerializationInterceptor`, route/controller
`SerializationOptions`, include/exclude field shaping, null skipping, and
content-length updates after body rewriting.
- Optional gzip response compression with `CompressionInterceptor`,
`CompressionOptions`, `Accept-Encoding` negotiation, `Vary` handling, and
content-length updates.
- Optional multipart file upload helpers with `BootRequest::multipart_form`,
`MultipartOptions`, text field and uploaded-file accessors, body/count/
per-field/per-file limits, Nest-style `#[uploaded_file]` /
`#[uploaded_files]` parameter macros, and automatic multipart OpenAPI
request-body metadata.
- Optional provider-backed static file serving with `StaticModule`,
`StaticFileService`, GET/HEAD catch-all routes, index-file support, SPA
fallback, cache-control headers, content-type detection, and traversal
protection.
## Priority Order
1. Parameter extraction macros
2. OpenAPI metadata and generator
3. Validation pipeline (implemented)
4. Module encapsulation, dynamic modules, provider lifecycle scopes, and
application enhancers (implemented)
5. Middleware (implemented)
6. WebSocket gateways (implemented)
7. Microservice transports (implemented)
8. Technique modules: config, cache, schedule, queues, logging, versioning, file upload
This order maximizes developer-facing Nest familiarity before adding broad
transport integrations.
## Out Of Scope
GraphQL is intentionally out of scope for this roadmap. A3S Boot should focus
on HTTP, SSE, WebSocket gateways, message transports, and the Nest-style module
and controller experience. If GraphQL is ever needed, it should be evaluated as
a separate companion crate rather than part of the core parity plan.
## Milestone 1: Parameter Extraction Macros
Nest equivalent:
- `@Body()`
- `@Body("field")`
- `@Param("id")`
- `@HostParam("account")`
- `@Query()`
- `@Headers("x-request-id")`
- `@Ip()`
- `@Req()`
Proposed A3S Boot shape:
```rust
#[controller("/cats")]
impl CatsController {
#[get("/{id}")]
async fn find_one(
&self,
#[param("id")] id: String,
#[query] query: FindCatQuery,
#[header("x-request-id")] request_id: Option<String>,
#[ip] ip: Option<String>,
) -> Result<CatDto> {
self.cats.find_one(id, query, request_id, ip).await
}
#[get("/host")]
#[host("{account}.example.com")]
async fn host_scoped(
&self,
#[host_param("account")] account: String,
) -> Result<CatDto> {
self.cats.find_for_account(account).await
}
#[post("/", status = 201)]
async fn create(&self, #[body] dto: CreateCatDto) -> Result<CatDto> {
self.cats.create(dto).await
}
}
```
Completed tasks:
- Extend `a3s-boot-macros` to parse attributes on route method arguments.
- Support `#[body]`, `#[request]`, `#[param("name")]`, `#[params]`,
`#[query]`, `#[query("name")]`, `#[header("name")]`, `#[headers]`,
`#[host_param("name")]`, and `#[ip]`.
- Support host-scoped controller and route macros through `#[host("...")]`,
plus explicit `RouteDefinition::with_host(...)` and
`ControllerDefinition::with_host(...)` APIs.
- Generate a wrapper that receives `BootRequest`, extracts typed values, then
calls the original method.
- Keep existing direct DTO body handlers working.
- Decide extraction errors:
- missing required path/query/header values should map to `BootError::BadRequest`
- type decode failures should map to `BootError::BadRequest`
- optional values should use `Option<T>`
- Add macro compile errors for unsupported combinations, duplicate body args,
or non-simple patterns.
Acceptance:
- Macro tests cover every extractor type.
- Existing macro tests still pass.
- README examples show `#[body]`, `#[param]`, and `#[query]`.
- `cargo test --test macros --test controllers` passes.
## Milestone 2: OpenAPI Metadata And Generator
Nest equivalent:
- `@nestjs/swagger`
- `@ApiTags`
- `@ApiOperation`
- `@ApiResponse`
- `@ApiParam`
- `@ApiQuery`
- `@ApiBearerAuth`
Proposed A3S Boot shape:
```rust
#[controller("/cats")]
#[tag("cats")]
impl CatsController {
#[get("/{id}")]
#[operation(summary = "Find a cat")]
#[response(status = 200, ty = CatDto)]
#[response(status = 404, description = "Cat not found")]
async fn find_one(&self, #[param("id")] id: String) -> Result<CatDto> {
self.cats.find_one(id).await
}
}
```
Tasks:
- Add route metadata storage to `RouteDefinition`. (Implemented)
- Add metadata fields for tags, operation id, summary, description, params,
query, request body, response bodies, status codes, auth requirements, and
deprecation. (Core fields implemented)
- Add a schema abstraction that can use a crate such as `schemars` without
coupling the core to it unless a feature is enabled. (Implemented with
`OpenApiSchema` and optional `openapi-schemas`)
- Add `OpenApiDocument` generation from `BootApplication`. (Implemented)
- Add optional route to serve JSON, for example `/openapi.json`. (Implemented)
- Add optional Swagger UI route backed by a generated JSON document.
(Implemented)
- Preserve adapter neutrality. (Implemented)
- Add Nest-style OpenAPI macros such as `#[tag]`, `#[operation]`,
`#[api_param]`, `#[api_query]`, `#[api_header]`, `#[response]`,
single and named request/response examples, request/response media types,
response header documentation, `#[bearer_auth]`, `#[api_security]`,
`#[api_cookie_auth]`, `#[api_key_auth]`, `#[oauth2_auth]`,
`#[open_id_connect_auth]`, `#[api_extra_model]`, and auth metadata
attributes. (Implemented)
- Add advanced schema helpers for extra model registration, `allOf` / `oneOf` /
`anyOf` composition, string enums, nullable fields, formats, descriptions,
required object properties, additional properties, and mapped-type-style
partial/pick/omit object schema transforms. (Implemented)
- Add document-level OpenAPI metadata for servers, external docs, and described
tags. (Implemented)
- Add operation-level server/external docs metadata and schema discriminator
helpers for polymorphic OpenAPI schemas. (Implemented)
- Add OpenAPI vendor extension support for operations, controller defaults,
macros, and schema objects. (Implemented)
- Add advanced parameter metadata for style/explode serialization hints,
deprecated and allowReserved flags, and single or named parameter examples.
(Implemented)
- Add route-level and controller-level OpenAPI exclusion support.
(Implemented)
- Add reusable OpenAPI components beyond schemas, including responses,
parameters, examples, request bodies, and headers, with operation-level `$ref`
helpers. (Implemented)
- Add optional schema component generation from `schemars`. (Implemented)
Acceptance:
- A sample controller can generate a valid OpenAPI 3 document.
- The generated document includes paths, methods, inferred and explicit params,
request body, responses, single and named request/response examples,
response headers, non-JSON media types, tags, described tags, servers,
external docs, operation-level servers/external docs, security requirements,
generated security schemes, extra schema components, composed schemas,
discriminator mappings, vendor extensions, advanced parameter metadata,
route/controller exclusions, OAuth2 flows, and OpenID Connect discovery
schemes.
- A generated Swagger UI route can load the generated JSON document.
- JSON examples in README are generated from tested code paths.
- OpenAPI tests validate a representative document with `serde_json`.
## Milestone 3: Validation Pipeline
Nest equivalent:
- `ValidationPipe`
- transform and whitelist options
- DTO-level validation
Proposed A3S Boot shape:
```rust
#[derive(Debug, Deserialize)]
struct CreateCatDto {
name: String,
age: Option<u8>,
}
impl Validate for CreateCatDto {
fn validate(&self) -> Result<()> {
if self.name.trim().is_empty() {
return Err(BootError::BadRequest("name is required".to_string()));
}
Ok(())
}
}
```
Tasks:
- Add a small `Validate` trait in core or a `validation` feature. (Implemented
in core)
- Integrate validation after DTO extraction and before handler invocation.
(Implemented with route validation hooks inside the around-interceptor chain,
after request pipes and before the handler)
- Support explicit validation pipe composition for projects that prefer a third
party crate such as `garde` or `validator`. (Implemented through ordinary
`Pipe` composition plus explicit `Validate` implementations)
- Support request body, params, and query validation. (Implemented)
- Support Nest-style whitelist and forbid-non-whitelisted policies for body,
query, and params validators. (Implemented with `ValidationOptions` and
explicit `ValidationSchema` field metadata)
- Support Nest-style transform policies for body, query, params, WebSocket
message data, and transport payload validators. (Implemented by rewriting
downstream request/message data from the validated DTO shape when
`ValidationOptions::transform(true)` is enabled)
- Support Nest-style validation option macros and scoped option APIs.
(Implemented with `#[validate(...)]`,
`ControllerDefinition::with_validation_options(...)`, and
`BootApplicationBuilder::use_global_validation_options(...)`, including
registered WebSocket and transport payload validators)
- Reduce whitelist metadata boilerplate for common DTOs. (Implemented with
`#[derive(ValidationSchema)]` for named structs)
- Add consistent validation error response mapping. (Implemented through
`BootError::BadRequest` / HTTP 400)
Acceptance:
- Invalid JSON body DTOs return HTTP 400 with contextual messages. (Covered)
- Invalid query/param DTOs return HTTP 400. (Covered)
- Whitelist validation can strip unknown body, query, and path fields before
handlers run, or reject those requests when forbid-non-whitelisted is enabled.
(Covered)
- Transform validation can expose serde defaults and renamed DTO fields to
downstream body, query, path, WebSocket message data, and transport payload
handlers. (Covered)
- Validation options can be applied through Nest-style route/controller macros
and through global/controller builder APIs, including registered protocol
payload validators. (Covered)
- Validation can be enabled globally, controller-level, and route-level.
(Covered through `use_global_validation`, `ControllerDefinition::with_validation`,
`RouteDefinition::with_validation`, protocol `with_validation()` APIs, and
`#[validate]`)
- Validation does not run for raw handlers unless explicitly configured.
(Covered)
## Milestone 4: Module Encapsulation, Dynamic Modules, Provider Scopes, And Application Enhancers
Nest equivalent:
- module `exports`
- re-exported modules
- global modules
- dynamic modules
- provider scopes: singleton, request, transient
- singleton provider lifecycle hooks, including shutdown phases
- `enableShutdownHooks`
- request-scoped controllers
- provider aliases / `useExisting`
- forward-reference-style provider dependencies
- module-level `forwardRef(() => Module)`
- lazy module loading
- DI-managed global enhancers through `APP_GUARD`, `APP_PIPE`,
`APP_INTERCEPTOR`, and `APP_FILTER`
Current gap:
`a3s-boot` previously registered providers into one resolved application
container. Boot now creates module-scoped provider registries. A module can see
its own providers plus exported providers from imports and global modules.
Dynamic modules can produce imports, providers, exports, controllers, and routes
from runtime configuration. Provider definitions can also choose singleton,
request-scoped, or transient lifecycle behavior. Singleton providers can opt
into module init, application bootstrap, module destroy, before application
shutdown, and application shutdown hooks. Managed HTTP and microservice hosts
can enable Nest-style shutdown hooks so OS signals close the application through
the same signal-aware lifecycle phases.
Request-scoped handler factories rebuild route/controller state from the current
request's module context. Macro controllers automatically use provider-backed
routes when their own scope or an eager dependency graph is contextual.
Singleton dependency trees automatically inherit request context without
changing their declared cache scope. Transient dependencies are cached per
inquirer inside a `ContextId`: one consumer reuses its transient instance, while
different consumers or contexts remain isolated. Direct contextless transient
lookups remain fresh per call for compatibility. `#[injectable]` emits typed,
named, optional, and lazy dependency metadata; hand-written factories can
declare the same graph explicitly without Boot probing factories and repeating
their side effects. Provider aliases let one token delegate to an existing
provider token without changing the target provider's lifecycle scope.
Explicit module-level forward imports can model deliberate circular module
relationships, while ordinary module import cycles still report the active
module chain during sync and async application graph builds. Singleton provider
factories are initialized after all module provider tokens are registered, so
factories can depend on providers declared later in the same module.
`LazyModuleLoader` can register complete provider-only module graphs on demand,
including forward imports, reuse eagerly registered modules, and resolve async
singleton factories through `load_async(...)`. Late global lazy modules are
rejected before factory execution because mutating global visibility would
invalidate already initialized singleton plans. `ModuleRef` can resolve
providers in a fresh temporary context or reuse a caller-supplied `ContextId`,
bind a context with `context_scope(...)`, and dynamically create unregistered
`FromModuleRef` values. `ContextIdFactory` creates standalone contexts and
discovers the identity attached automatically to each HTTP request.
`ProviderRef<T>` can capture a module context and resolve a provider lazily,
which gives Rust code an explicit forward-reference-style escape hatch while
keeping ordinary provider cycles diagnostic. It can also resolve through a
caller-supplied context while preserving the original inquirer. Contextual
factories use non-owning context views so cached lazy refs cannot retain their
own request cache. Provider construction uses panic-safe, branch-local
resolution paths plus single-flight cache slots and cross-thread wait-cycle
diagnostics. Provider definitions can also carry typed application-enhancer
markers that map to Nest's `APP_GUARD`, `APP_PIPE`, `APP_INTERCEPTOR`, and
`APP_FILTER` provider registrations. HTTP, WebSocket, and transport variants
resolve from the declaring module against the current request or message
`ContextId`, so private dependencies remain injectable without widening module
exports. HTTP requests, WebSocket messages, and transport messages each receive
an isolated context; sequential interceptor retries reuse the original context.
Pipelines compose builder globals before provider globals, provider globals
retain module/provider declaration order, and handler-local hooks remain last;
exception filters keep their existing local-to-global handling direction. Lazy
modules reject `APP_*` providers before any factory executes because existing
application pipelines cannot be mutated after build.
Tasks:
- Introduce module-scoped provider registries. (Implemented)
- Add explicit provider exports and imported-module visibility. (Implemented)
- Support re-exporting imported modules. (Implemented through transitive token
exports)
- Add global modules for opt-in application-wide providers. (Implemented through
`Module::is_global`)
- Add dynamic module builders for configuration-driven providers. (Implemented
with `DynamicModule`)
- Add module route prefixes comparable to Nest `RouterModule.register(...)`,
including import-tree composition and `DynamicModule::route_prefix(...)`.
(Implemented)
- Preserve direct host access through `BootApplication::get(...)` where it makes
sense, but avoid accidentally exposing private feature-module providers.
(Implemented; root scopes and global exports are visible to the host)
- Add provider lifecycle scopes comparable to Nest singleton, request, and
transient providers. (Implemented)
- Make request-scoped providers reuse one instance per resolution context,
including dependencies resolved inside request-scoped provider factories.
(Implemented)
- Add public `ContextId` / `ContextIdFactory` APIs plus `ModuleRef` and
`ProviderRef<T>` context-aware resolution, including named and optional
variants. (Implemented)
- Reuse transient providers per inquirer within one context while keeping
different consumers and contexts isolated and direct contextless transient
lookup fresh. (Implemented)
- Attach one discoverable `ContextId` to each dispatched HTTP request.
(Implemented through `BootRequest::context_id()` and
`ContextIdFactory::get_by_request(...)`)
- Propagate request context through eager singleton and transient dependency
graphs without rewriting their declared scope. (Implemented through
`ProviderDependency` metadata generated by `#[injectable]` or declared on
`ProviderDefinition`)
- Reject async factories and singleton lifecycle-hook providers whose effective
dependency graph is contextual. (Implemented during graph finalization)
- Add singleton provider lifecycle hooks for init, bootstrap, module destroy,
before application shutdown, and application shutdown. (Implemented)
- Add Nest-style shutdown hook enabling for managed HTTP and microservice
hosts. (Implemented with `enable_shutdown_hooks(...)` and default
`SIGINT`/`SIGTERM` support)
- Add request-scoped route/controller and transport message-handler factories.
(Implemented, with automatic provider-backed routes and message patterns for
contextual macro controllers)
- Add provider aliases comparable to Nest `useExisting`. (Implemented)
- Add lazy provider handles comparable to the useful provider side of Nest
`forwardRef(...)`. (Implemented with `ProviderRef<T>`)
- Add module-level forward imports comparable to Nest
`forwardRef(() => Module)`. (Implemented with `Module::forward_imports`,
`DynamicModule::forward_import(...)`, and `#[module(forward_imports = [...])]`)
- Add Nest-style `ModuleRef::resolve(...)` and `ModuleRef::create(...)`
runtime APIs. (Implemented)
- Add contextual diagnostics for transient and request-scoped provider
dependency cycles. (Implemented)
- Add contextual diagnostics for module import cycles. (Implemented)
- Add order-independent singleton provider graph initialization. (Implemented)
- Add provider-only lazy module loading with cached module refs. (Implemented
with full-graph forward-import planning; newly loaded globals are rejected)
- Add typed provider-backed application enhancers corresponding to Nest
`APP_GUARD`, `APP_PIPE`, `APP_INTERCEPTOR`, and `APP_FILTER`, including
WebSocket and transport variants. (Implemented with `app_*::<T>()` and
`with_app_*::<T>()` provider APIs)
- Resolve application enhancers from their declaring module with automatic
scope bubbling and the active HTTP request, WebSocket message, or transport
message `ContextId`; preserve that id across sequential interceptor retries.
(Implemented)
- Preserve deterministic builder-global, provider-global, and local-hook order
without widening module visibility. (Implemented)
- Reject `APP_*` providers in lazy-loaded modules before provider factories
execute. (Implemented)
- Make testing pipeline overrides replace provider-backed components by their
original concrete type and retain original enhancer markers across provider
overrides. (Implemented)
- Add custom context-id selection strategies, durable provider subtrees, and
request-object registration for arbitrary context ids. (Future work)
Acceptance:
- A provider declared but not exported by an imported module is not visible to
the importing module. (Covered)
- Exported providers are visible transitively according to explicit imports.
(Covered)
- Duplicate-provider checks respect module scope. (Covered)
- Existing simple module examples continue to work or have a documented migration.
(Covered; root module providers remain visible through `BootApplication::get`)
- Direct contextless transient lookups remain fresh, while repeated transient
injection into one inquirer is reused and different inquirers or context ids
receive distinct instances. (Covered)
- Request-scoped providers are cached per context and are isolated from other
contexts; a caller can reuse that cache through `resolve_with_context(...)`
or `ModuleRef::context_scope(...)`. (Covered)
- Singleton providers with eager request-scoped dependencies are cached once per
context, contextual transients follow per-inquirer reuse, and opaque factories
cannot capture a startup-only request instance. (Covered)
- Singleton provider lifecycle hooks run with module lifecycle hooks, reject
request/transient provider scopes, and receive explicit shutdown signal labels
through signal-aware close helpers. (Covered)
- Managed HTTP and microservice hosts can close through signal-aware lifecycle
hooks when a configured shutdown signal wins the serve race. (Covered)
- Request-scoped and dependency-bubbled controller handlers are rebuilt for
each request and share the same request-scoped provider cache as
`BootRequest::get(...)`. (Covered)
- Request-scoped, transient, and dependency-bubbled message controllers resolve
once per transport dispatch, reuse the same controller and `ContextId` across
interceptor retries, and isolate later messages. (Covered)
- Provider aliases resolve the same singleton instance, preserve request-scoped
resolution, and reject alias cycles with contextual errors. (Covered)
- `ProviderRef<T>` resolves lazily, can break an intentional singleton
dependency cycle, supports named and optional macro injection, and preserves a
captured request scope and inquirer; explicit context resolution reuses a
caller-supplied id. (Covered)
- Context caches release providers that contain lazy refs, construction paths
recover after caught panics, parallel branches do not share sibling frames,
and concurrent single-flight waits distinguish real cycles from converging
dependency graphs. (Covered)
- `ModuleRef::resolve(...)` creates a fresh resolution context,
`resolve_with_context(...)` and its named/optional variants reuse an explicit
context, and `ModuleRef::create(...)` can instantiate `FromModuleRef` values
with distinct synthetic inquirers without registering them. (Covered)
- Every dispatched HTTP request exposes one distinct context identity through
`BootRequest::context_id()` and `ContextIdFactory::get_by_request(...)`.
(Covered)
- Provider-backed HTTP application guards, pipes, interceptors, and filters
share the request context across direct and module routes, and application
filters can handle early routing errors. (Covered)
- Provider-backed HTTP enhancers also apply to framework-provided routes, and
application filters can handle unmatched application routes. (Covered)
- Provider-backed WebSocket and transport application enhancers resolve from a
fresh message context, share one exact context within a dispatch, and isolate
later messages on the same connection or pattern. (Covered)
- Sequential HTTP, WebSocket, and transport interceptor retries reuse the
original request or message context. (Covered)
- Application enhancers resolve through their declaring module, can inject its
private providers, retain deterministic builder/provider/local order, and do
not make those dependencies visible to unrelated handler modules. (Covered)
- Typed custom and named provider definitions can retain application-enhancer
markers. (Covered)
- Alias, value, and async provider definitions can retain the same markers, and
contextual async or lifecycle enhancer graphs are rejected before factory
execution. (Covered)
- Testing pipeline overrides replace provider-backed application enhancers by
original concrete type, provider overrides retain the original marker slot,
and lazy module loading rejects `APP_*` providers before factories run.
(Covered)
- Graph-level enhancer replacement uses `override_provider(...)` with the
original typed or named token, runs before singleton construction, suppresses
the original provider lifecycle, and retains its pipeline marker; pipeline
overrides remain type-safe component-view replacements. (Covered)
- Transient and request-scoped provider cycles report the active token chain.
(Covered)
- Module import cycles report the active module chain during sync and async
builds. (Covered)
- Explicit forward imports allow deliberate circular module edges without
weakening ordinary import-cycle diagnostics, and provider cycles still use
lazy `ProviderRef<T>` handles. (Covered)
- Singleton provider factories can resolve dependencies declared later in the
same module, including sync factories that depend on async-built singletons in
async builds. (Covered)
- Declared async dependencies are seeded before their consumers across local,
imported, forward-imported, and global module edges; cycles and missing
dependencies fail before factory execution. (Covered)
- Lazy module loading returns cached module refs, reuses eagerly imported
modules, resolves imports/exports/forward imports, supports async singleton
providers through `load_async(...)`, rejects new late globals, and does not
register controllers, routes, gateways, middleware, message patterns, or
lifecycle hooks. (Covered)
## Milestone 5: Middleware
Nest equivalent:
- `NestMiddleware`
- `MiddlewareConsumer`
- route-scoped middleware
Tasks:
- Add middleware trait that can inspect/mutate `BootRequest` before guards, the
around-interceptor chain, and pipes. (Implemented)
- Allow middleware to short-circuit with `BootResponse`. (Implemented through
`MiddlewareOutcome::Respond`)
- Support global, module/controller, and route-scoped registration.
(Implemented)
- Add Nest-style `MiddlewareConsumer` with `apply`, `exclude`, `for_routes`,
and `for_all_routes` for module-scoped route selection. (Implemented)
- Preserve order: middleware, guards, the nested around-interceptor chain,
pipes, validation, and the handler; legacy `after` hooks unwind in reverse,
and filters receive only unrecovered errors. (Covered)
- Ensure adapter-level request validation remains before middleware.
(Covered for Axum)
Acceptance:
- Middleware can add request headers or context values before a handler.
(Covered)
- Middleware can reject a request before guards run. (Covered)
- Route-scoped middleware only applies to matching route groups. (Covered)
- Consumer route selectors support method-specific include/exclude rules and
module-local or module-prefixed paths. (Covered)
- Pipeline ordering is covered by tests. (Covered)
## Milestone 6: WebSocket Gateways
Nest equivalent:
- `@WebSocketGateway()`
- gateway namespaces
- rooms and broadcasts
- `@SubscribeMessage()`
- `@MessageBody()` and `@MessageBody("field")`
- `@ConnectedSocket()`
- `@WebSocketServer()`
- gateway lifecycle hooks
- gateway guards/pipes/interceptors
Tasks:
- Define adapter-neutral WebSocket connection and message traits. (Implemented)
- Add gateway registration API. (Implemented through `WebSocketGatewayDefinition`,
`Module::gateways`, `DynamicModule::gateway`, and application builder support)
- Add `#[websocket_gateway]` and `#[subscribe_message]` macros. (Implemented)
- Add typed message-body DTO binding and validation for subscription handlers
comparable to Nest `@MessageBody()` plus `ValidationPipe`. (Implemented)
- Add field-level message body binding comparable to Nest
`@MessageBody("field")`. (Implemented with `#[message_body("field")]` and
`WebSocketMessage::data_field_as(...)` helpers)
- Add connected-socket binding for subscription handlers comparable to Nest
`@ConnectedSocket()`. (Implemented with `WebSocketGatewayConnection` method
arguments and `subscribe_with_connection(...)`)
- Add gateway server binding comparable to Nest `@WebSocketServer()`.
(Implemented with `WebSocketGatewayServer` method arguments,
`WebSocketGatewayDefinition::server()`, and `subscribe_with_server(...)`)
- Add gateway lifecycle hooks comparable to Nest `OnGatewayInit`,
`OnGatewayConnection`, and `OnGatewayDisconnect`. (Implemented with
`#[on_gateway_init]`, `#[on_gateway_connection]`,
`#[on_gateway_disconnect]`, and explicit hook builders)
- Add logical gateway namespaces plus room membership, direct emits, and
broadcast helpers comparable to the high-value Socket.IO-backed Nest gateway
workflow. (Implemented)
- Implement Axum WebSocket adapter support behind the `axum` feature.
(Implemented)
- Reuse DI and pipeline concepts where possible. (Implemented with provider-backed
gateways and gateway- or subscription-specific pipe/guard/interceptor/filter
hooks)
Acceptance:
- A gateway can accept a WebSocket connection and dispatch messages by event
name. (Covered)
- Gateway init, connection, and disconnect hooks run through explicit APIs,
provider-backed macros, and application bootstrap. (Covered)
- Gateway handlers can use providers. (Covered)
- Gateway handlers can accept typed message-body DTOs, validate them, and apply
transform/whitelist policies before handler invocation. (Covered)
- Gateway handlers can bind individual message body fields, including optional
fields, defaults, and parse pipes. (Covered)
- Gateway handlers can access the current connection alongside raw or typed
message bodies. (Covered)
- Gateway handlers and lifecycle hooks can access a gateway-wide server handle
for connection inspection, direct emits, and broadcasts. (Covered)
- Gateway and subscription guards/interceptors/pipes plus application-wide
gateway guards/interceptors/pipes run in Nest-style deterministic order.
(Covered)
- Gateway interceptors can use reusable `CallHandler` access to short-circuit,
recover or transform errors, and retry the downstream pipeline while
retaining legacy `before` / `after` compatibility. (Covered)
- Gateway exception filters can handle matching message dispatch errors and map
unrecovered errors to outbound WebSocket messages, including application-wide
WebSocket filters. (Covered)
- Gateways can track active connection ids, join/leave rooms, and deliver
direct, room-scoped, or gateway-wide messages to adapter-backed connections.
(Covered)
- Tests cover in-process adapter behavior and Axum integration. (Covered)
## Milestone 7: Microservice Transports
Nest equivalent:
- TCP, Redis, NATS, MQTT, RabbitMQ, Kafka, gRPC, and custom transports.
- `@MessagePattern()` and `@EventPattern()` handlers.
- `@Payload()` and `@Payload("field")`.
Tasks:
- Define an adapter-neutral message transport trait. (Implemented with
`MessageTransport`)
- Add message pattern registration APIs and macros. (Implemented with
`MessagePatternDefinition`, `Module::message_patterns`,
`BootApplicationBuilder::message_pattern`, `#[message_controller]`,
`#[message_pattern]`, and `#[event_pattern]`)
- Add dispatch-scoped request/event pattern factories and automatically select
them for request-scoped, transient, or dependency-bubbled macro message
controllers. (Implemented with `request_scoped(...)`, `event_scoped(...)`,
and provider-backed macro patterns)
- Add field-level payload binding comparable to Nest `@Payload("field")`.
(Implemented with `#[payload("field")]` and
`TransportMessage::data_field_as(...)` helpers)
- Reuse provider lookup and pipeline primitives. (Implemented with
provider-backed module registration plus transport-specific guards,
interceptors, pipes, exception filters, payload validation, and
controller/pattern pipeline decorators)
- Start with an in-process test transport before external brokers.
(Implemented with `InProcessTransport`)
- Add one production transport only after the core contract is stable.
(Implemented first with optional `TcpTransport`, followed by optional
`RedisTransport`, `NatsTransport`, `MqttTransport`, and
`RabbitMqTransport`, `KafkaTransport`, and `GrpcTransport`.)
Acceptance:
- A module can register message handlers independently from HTTP routes.
(Covered)
- Message handlers can use providers and validation. (Covered)
- Scoped message handlers can inject private declaring-module providers, reuse
one handler/controller across an interceptor retry, and receive a fresh
context on the next request-response or event message. (Covered)
- Message handlers can bind individual payload fields, including optional
fields, defaults, and parse pipes. (Covered)
- Application-wide transport guards/interceptors/pipes run before and around
pattern-scoped hooks in Nest-style deterministic order. (Covered)
- Transport interceptors can use reusable `CallHandler` access to short-circuit,
recover or transform errors, and retry the downstream pipeline while
retaining legacy `before` / `after` compatibility. Event-pattern replies are
discarded even when an interceptor short-circuits. (Covered)
- Tests cover request-response and event-only patterns. (Covered)
- Handler errors preserve `BootError` HTTP exception semantics across TCP,
Redis, NATS, MQTT, RabbitMQ, Kafka, and gRPC request-response transports.
(Covered)
- Transport exception filters can handle matching message dispatch errors and
map unrecovered errors to request-response replies or handled event errors,
including application-wide transport filters. (Covered)
## Milestone 8: Technique Modules
Nest equivalent areas:
- configuration (implemented)
- cache (implemented)
- task scheduling (implemented)
- queues (implemented)
- application events (implemented)
- CQRS command, query, and event buses (implemented)
- authentication strategies and guards (implemented)
- database providers and transactions (implemented)
- request context / AsyncLocalStorage-style request state (implemented)
- health checks (implemented)
- outbound HTTP client module (implemented)
- logging (implemented)
- API versioning (implemented)
- serialization (implemented)
- compression (implemented)
- MVC view rendering and `@Render()`-style responses (implemented)
- streamable file and download responses (implemented)
- file upload (implemented)
- static assets and SPA shells (implemented)
- security helpers such as CORS, CSRF, helmet-like headers, process-local rate
limiting, and a provider-neutral atomic boundary for shared rate limits
(implemented)
- sessions (implemented)
Tasks:
- Prefer companion crates or feature modules over bloating the core.
- Keep configuration ACL-first.
- Define integration points through providers, middleware, guards, interceptors,
and adapters.
Acceptance:
- Each technique module has its own tests and docs.
- Core remains usable without the technique modules.
- Modules compose through the same provider and lifecycle APIs.
- Configuration can load ACL into typed providers, use environment defaults,
and participate in module imports/exports. (Covered)
- HTTP clients can be registered as module providers, use base URL/default
header/timeout options, send and decode JSON request/response bodies, support
named/global exports, build options asynchronously, and swap backends in
tests. (Covered)
- CQRS can register command, query, and event handlers; dispatch typed command
and query results; publish typed events to multiple handlers; resolve providers
from handler context; export buses globally; and reject duplicate command or
query handlers. (Covered)
- Authentication can register bearer or custom strategies, select strategies
from guard configuration or route metadata, attach principals to requests,
allow public routes, and enforce role/scope metadata. (Covered)
- Database can register a provider-backed facade, use replaceable backends,
execute statements, query adapter-neutral rows, run commit/rollback
transactions, support named/global exports, and expose an in-memory backend
for tests. (Covered)
- Request context can bind task-local request data across middleware, guards,
interceptors, pipes, handlers, and called provider methods; expose request id,
path params, query values, headers, metadata, pipeline-local values, and auth
principal data when authentication is enabled. (Covered)
- Cache can register typed providers, cache serde values with TTL, participate
in module imports/exports, and cache successful non-streaming GET responses
through `CacheInterceptor` with route/controller cache keys and TTL metadata.
(Covered)
- Schedule can register typed providers, run timeout/interval/cron jobs through
lifecycle-managed in-process tasks, expose Nest-style schedule macros, and
participate in module imports/exports. (Covered)
- Queue can register typed providers, enqueue serde JSON jobs through
`a3s-lane`, run named processors through lifecycle-managed workers, and
participate in module imports/exports. (Covered)
- Application events can register an `a3s-event` backed `EventEmitter`
provider, dispatch typed JSON payloads to exact or wildcard listeners, expose
Nest-style listener macros, retain events through the underlying `EventBus`,
accept custom `a3s-event` providers, and participate in module
imports/exports. (Covered)
- Health checks can register provider-backed async indicators, expose a typed
`HealthCheckService`, return JSON readiness reports, and map unhealthy
reports to HTTP 503. (Covered)
- Logging can register typed providers, write structured records through
pluggable sinks, capture records in tests, and expose request/worker logging
integration points without forcing a concrete backend. (Covered)
- API versioning can route by URI segment, request header, or media type
parameter; inherit controller versions; use default versions; expose
version-neutral routes; reject duplicate routes only when version metadata
overlaps; and expose Nest-style version macros. (Covered)
- Serialization can shape JSON response objects and arrays through global
interceptors plus route/controller metadata, leave non-JSON responses
unchanged, keep content length valid after rewriting, and expose Nest-style
serialization macros. (Covered)
- Compression can gzip eligible responses when requested by `Accept-Encoding`,
skip too-small, streaming, and already-encoded responses, set `Vary`, and keep
content length valid after rewriting. (Covered)
- Streamable file responses can wrap in-memory bytes or byte streams, set
content type, content length, inline or attachment content disposition, and
reach adapters as streamed bytes instead of SSE events. (Covered)
- View rendering can register a provider-backed renderer, render serializable
route return values into HTML responses, use module imports/exports, expose
explicit route/controller helpers, and mirror Nest `@Render()` with
`#[render(...)]`. (Covered)
- File upload can parse adapter-neutral multipart forms, expose repeated text
fields and uploaded files, reject non-multipart or malformed requests,
enforce body, field, file, and count limits, extract uploads through
Nest-style controller parameter macros, and document upload routes as
`multipart/form-data`. (Covered)
- Static assets can be served from an imported module with GET and HEAD routes,
optional SPA fallback, cache-control headers, basic content-type detection,
hidden dotfile defaults, and root traversal protection. (Covered)
- Security helpers can handle CORS preflight and actual response headers, add
helmet-like response headers, reject invalid CSRF tokens on unsafe methods,
enforce in-memory fixed-window rate limits, and delegate atomic acquisitions
to an application-supplied shared provider without exposing plaintext
credentials. Boot does not select a distributed backend. (Covered)
- Sessions can register a provider-backed `SessionManager`, expose
request-bound `Session` handles through `BootRequest::session()` and
Nest-style `#[session]` arguments, bind session ids before handlers, persist
session cookies after handlers, and support in-memory or custom stores.
(Covered)
- Response cookies can be written and expired through typed `BootResponse`
helpers instead of hand-built `Set-Cookie` strings. (Covered)
- Response passthrough can set status codes, headers, and cookies through
`ResponsePassthrough` and Nest-style `#[res]` arguments without exposing
adapter-native response objects. (Covered)
- Request cookies can be read through typed `BootRequest` helpers and bound
through Nest-style `#[cookie]` and `#[cookies]` arguments. (Covered)
- JSON body fields can be read through typed `BootRequest` helpers and bound
through Nest-style `#[body("field")]` arguments. (Covered)
- Testing utilities can compile Nest-style testing modules, override imported
modules and providers before controllers are built, override HTTP,
WebSocket, and transport pipeline components including provider-backed
application enhancers, resolve providers, and dispatch in-process requests.
(Covered)
- Discovery and reflector utilities can snapshot modules, module graph edges,
provider tokens, exports, HTTP route metadata, WebSocket gateways, and
message patterns from a built application. (Covered)
## Immediate Next Task
Continue the Nest framework parity audit and implement the next missing
framework capability. Keep GraphQL out of scope.
Suggested implementation sequence:
1. Continue the Nest framework parity audit with the next non-GraphQL core
capability.
2. Continue defining integrations through providers, middleware, guards,
interceptors, or adapters instead of adding one-off framework hooks.
3. Add crate-local tests and README examples for each chosen framework module.
4. Run:
```sh
cargo fmt --all
cargo test --test macros --test controllers
cargo test --all-targets
cargo test --no-default-features
cargo clippy --all-targets -- -D warnings
cargo clippy --no-default-features --all-targets -- -D warnings
git diff --check
```