#[module] macro declares the composition graph; #[injectable] marks types as providers resolved through Arc; #[set_metadata] and #[roles] attach string metadata to route handlers for guards and other pipeline components to read.
All macros are re-exported from nestrs::prelude::*.
#[module]
Declares a struct as an application module. Generates the Module trait implementation that builds the ProviderRegistry and Axum Router by walking the import graph.
Controller structs annotated with
#[controller] to register into the module’s router.Injectable structs annotated with
#[injectable] to register into the module’s provider registry.Other module types or
DynamicModule expressions whose exported providers are absorbed into this module’s registry.Provider types from this module’s registry to re-export so importing modules can resolve them.
Dynamic module imports
Theimports list also accepts DynamicModule expressions, which lets you conditionally include modules:
#[injectable]
Marks a struct as a provider that the DI container can construct and resolve as Arc<Self>. Generates the Injectable trait implementation with a construct method that the ProviderRegistry calls.
construct implementation calls registry.get::<OtherService>() for each field of type Arc<T> where T itself implements Injectable.
Scope variants
The default scope isSingleton (one instance per application container). Override it with the scope argument:
One of
"singleton" (default), "transient", or "request". Request scope requires NestApplication::use_request_scope() to be called before listen.Lifecycle hooks
Override any of these async methods on your type to hook into the application lifecycle:construct is synchronous. Perform async I/O in on_module_init or use ConfigurableModuleBuilder::for_root_async to await initialization before the DI graph constructs singletons.Full example with cross-module injection
#[set_metadata]
Attaches a key-value string pair to the route handler’s entry in MetadataRegistry. Evaluated at route registration time (compile-time macro expansion + runtime registration via impl_routes!).
Metadata key. Used by guards and middleware to look up the value via
MetadataRegistry::get(handler_key, key).Metadata value. All values are plain strings; serialize JSON yourself for structured data.
HandlerKey extension inserted by the router:
#[roles]
Shorthand for #[set_metadata("roles", "...")]. Sets the roles metadata key to a comma-separated string of role names. Intended to be consumed by role-aware guards such as XRoleMetadataGuard.
One or more role names as string literals. Multiple values are joined with commas in the metadata store.
Worked example: role-protected route
x-role: admin to receive 200. Sending any other role value yields 403.