Annotation reference¶
Every annotation in package:diana_annotation (re-exported by
package:diana/diana.dart). All annotations are const classes with no
runtime behaviour — they exist for the generator.
Notation: [x] optional positional parameter, {x} named parameter.
Dependency injection¶
@Injectable({Scope scope = Scope.singleton, Type? as, String? name})¶
Target: class. Marks a class as a provider in the DI graph. Instantiated through its public unnamed generative constructor; every constructor parameter is resolved at build time.
| Parameter | Meaning |
|---|---|
scope |
Lifecycle: Scope.singleton (default), Scope.request, Scope.transient. |
as |
Explicitly bind this provider to a type it implements/extends, taking precedence over auto-binding candidates. Build error if the class doesn't implement it, or if two providers claim the same type. |
name |
Qualifier. A named provider is only injectable through @Named(name). |
@Service(...), @Repository(...), @Component(...)¶
Target: class.
Semantic aliases of @Injectable with identical parameters and behaviour.
Use them to communicate a class's role.
@Named(String name)¶
Target: constructor parameter.
Selects the provider registered with qualifier name for this parameter.
enum Scope { singleton, request, transient }¶
See scopes.
Web¶
@RestController([String path = '/', Scope scope = Scope.singleton])¶
Target: class.
Declares an HTTP controller; all routes mount under path. The controller
joins the DI graph with the given scope (a controller depending on
request-scoped providers must itself be request-scoped). Requires a
part '<file>.diana.dart'; directive in the library.
@Get, @Post, @Put, @Delete, @Patch — ([String path = ''])¶
Target: method (public, instance).
Maps the method to the HTTP verb, at path relative to the controller
('' = the controller path itself). Paths use :name segments for path
parameters.
@HttpRoute(String method, String path)¶
Target: method.
Base class of the verb annotations; use directly for verbs without a
shorthand: @HttpRoute('HEAD', '/status'). method is upper-case.
@PathParam([String? name])¶
Target: parameter.
Binds a :name path segment. name defaults to the Dart parameter name.
Type: non-nullable String/int/double/bool/num. Conversion failure
→ 400.
@QueryParam([String? name, String? defaultValue])¶
Target: parameter.
Binds a query-string parameter. name defaults to the parameter name.
defaultValue is written as a string ('20') and converted like a real
value. A nullable parameter type makes it optional (bound to null when
absent); a non-nullable type without default is required (400 when
missing).
@Header([String? name])¶
Target: parameter.
Binds a request header, case-insensitively. Same type/nullability rules as
@QueryParam (no default value).
@Body()¶
Target: parameter.
Binds the request body. Parameter types: a DTO (@Json, hand-written
fromJson, or json_serializable), Map<String, dynamic>, List<Dto>, a
List of JSON primitives, String (raw text, any content type) or
FormData (multipart / urlencoded — see
uploads). Wrong content type →
415; malformed/mis-shaped bodies → 400; oversized multipart → 413. DTO
validators run before the handler.
@ResponseStatus(int code)¶
Target: method.
Overrides the success status code (e.g. 201). Applies to JSON, text and
void returns; ignored when the method returns DianaResponse (which
carries its own status).
@CrossOrigin({origins, methods, headers, exposedHeaders, credentials, maxAge})¶
Target: class (controller) or method (route).
Enables CORS with a policy that fully replaces the global
server.cors.* configuration (route > controller > global). Diana
registers the OPTIONS preflight automatically. Fields mirror the config
keys — see CORS.
@Consumes(List<String> mimeTypes)¶
Target: class (controller) or method (route); method replaces
controller entirely.
Restricts the request content types the route accepts; the body is decoded
with the matching registered BodyCodec (other content types → 415). The
listed set replaces the JSON default. Requires a codec-decoded @Body
parameter (Map, List or DTO). See
Content negotiation.
@Produces(List<String> mimeTypes)¶
Target: class (controller) or method (route); method replaces
controller entirely.
Declares the response formats the route can produce; the response is
encoded with the first type the request's Accept header allows (server
preference order; nothing acceptable → 406). Applies to JSON-encodable
returns only; cannot be combined with Stream returns. See
Content negotiation.
Lifecycle¶
@PostConstruct() / @PreDestroy()¶
Target: method (public instance, no parameters, void/Future<void>;
at most one of each per class; singleton providers only).
Run after construction during initialize() (dependency order) and during
graceful shutdown in dispose() (reverse order). See the
lifecycle guide.
Scheduling¶
@Scheduled({int? fixedRate, int? fixedDelay, String? cron, int initialDelay = 0, bool perIsolate = false})¶
Target: method (same signature rules as lifecycle hooks; singleton
providers only). Exactly one of fixedRate/fixedDelay (milliseconds) or
cron. Tasks start after initialization and stop on shutdown; fixedRate
skips overlapping ticks, fixedDelay re-arms after completion, cron fires
at each expression match (next occurrence computed after completion, so runs
never overlap). cron is a 6-field expression (second minute hour
day-of-month month day-of-week, Spring style; three-letter month/day names,
ranges, lists and */step) or a macro (@yearly, @monthly, @weekly,
@daily, @hourly), evaluated in the process's local time (initialDelay
does not apply). With multi-isolate serving, tasks run once per process
(main isolate only); perIsolate: true opts a task into running in every
isolate. See Observability.
Messaging (STOMP)¶
STOMP handlers on singleton providers. See the STOMP guide.
@MessageMapping(String destination)¶
Target: method. Handles STOMP SENDs to <appPrefix>/<destination>
(default prefix /app). Takes the payload (a String for the raw body, or
an @Json class) and, optionally, a second StompMessage parameter; a
non-void return (String or @Json, optionally Future) is published to
the @SendTo destination. destination must start with /.
@SendTo(String destination)¶
Target: method (with @MessageMapping). Publishes the method's return
value to destination (must start with /). Required when the method
returns a value.
Events¶
@EventListener()¶
Target: method (public instance, exactly one positional parameter — the
event type, a non-nullable class — returning void/Future<void>;
singleton providers only).
Registers the method as an application-event listener: it receives every
event published through DianaEventPublisher whose type matches the
parameter (subtypes included). Listeners are registered before
initialize(), dispatched in registration order and awaited. See the
events guide.
Authentication & authorization¶
These require the diana_auth package (the runtime types they wire in live
there). See the auth guide.
@Secured()¶
Target: class (REST/WebSocket controller or gRPC service) or route method; method replaces controller. Requires an authenticated principal — anonymous requests get 401. The generator appends a guard after the authentication middleware.
@RolesAllowed(List<String> roles)¶
Target: same as @Secured.
Requires the principal to hold any of roles (401 anonymous, 403
authenticated-but-missing-role). Implies @Secured.
@Principal()¶
Target: route-method parameter.
Binds the authenticated principal (AuthPrincipal or a subclass). A
non-nullable parameter throws 401 when unauthenticated; a nullable one
receives null.
JSON¶
@Json()¶
Target: class.
Generates $XFromJson/$XToJson into the class's part file; route
adapters use them automatically for @Body parameters and return values —
no fromJson/toJson boilerplate. Supported field types are listed in the
JSON guide. Requires a part directive and a public
unnamed constructor whose parameters match field names.
@JsonField({String? name})¶
Target: field (inside a @Json class).
Renames the field's JSON key.
WebSockets¶
@WebSocketController(String path, [Scope scope = Scope.singleton])¶
Target: class (must implement WebSocketHandler, e.g. by extending
BaseWebSocketHandler).
Registers the class as a WebSocket endpoint at path (which may contain
:name parameters, exposed via WebSocketSession.pathParameters). The
class joins the DI graph:
Scope.singleton(default) — one shared handler for all connections.Scope.transient— a fresh handler per connection.Scope.request— build error (not applicable to WebSockets).
Endpoint paths must be unique across the application. @UseMiddleware on
the class runs as handshake interceptors (blocking the upgrade on
short-circuit and propagating request attributes into the session); global
middleware and @ControllerAdvice do not apply to socket traffic. See the
WebSockets guide.
gRPC¶
@GrpcService()¶
Target: class (must extend a protoc-generated XServiceBase, i.e. a
package:grpc Service).
Registers the class as a gRPC service: it joins the DI graph as a
singleton (constructor injection, @Value, lifecycle apply) and the
generated DianaApp serves all @GrpcService classes on grpc.port
through package:diana_grpc (a dependency your app must declare). Cannot
be combined with other role annotations. See the
gRPC guide.
Persistence¶
Requires the diana_data package (the Database it works with lives
there). See the persistence guide.
@Transactional()¶
Target: method (must return Future) or class (all public
Future-returning methods) on a @Service/@Component/@Repository
provider that is extendable (not final/base/sealed).
Runs the method inside a database transaction via a generated proxy
subclass. Nesting joins the enclosing transaction as a savepoint
(propagation REQUIRED); an uncaught exception rolls back and rethrows.
@Table(String name)¶
Target: class (a @Json entity). Maps the entity to a database table
for query repositories;
column names are the fields' JSON keys (@JsonField(name:) doubles as the
column override).
Aspects¶
Method-level, on @Service/@Component/@Repository providers; the
methods must be public instance methods returning Future, and the class
must be extendable. Fixed composition order @Timed → @Cacheable →
@CircuitBreaker → @Retryable → @Transactional. See the
aspects guide.
| Annotation | Parameters | Meaning |
|---|---|---|
@Timed |
String? name (default Class.method) |
Duration/result metrics + a trace span via the observability provider (silent no-op without one) |
@Cacheable |
int ttlSeconds = 60, int maxEntries = 1024 |
Per-isolate TTL+LRU cache keyed by the argument list (or a shared backend via a DianaCacheStore provider); needs Future<T> with non-void T, no type parameters |
@Retryable |
int maxAttempts = 3, int backoffMs = 200, List<Type> retryOn = const [] |
Fixed-backoff retry; retryOn limits the exception types (empty = all) |
@CircuitBreaker |
int failureThreshold = 5, int resetTimeoutMs = 30000 |
Fail-fast after consecutive failures; half-open trial after the timeout |
Middleware¶
@GlobalMiddleware({int order = 0})¶
Target: class (must implement Middleware).
Registers the class as global middleware applied to every route, and makes
it an injectable singleton. Lower order runs first (outermost); ties
break by class name.
@UseMiddleware(List<Type> middleware)¶
Target: class (controller) or method (route).
Applies the listed middleware — in order — to all routes of a controller or
to one route. Each type must be an injectable singleton implementing
Middleware (verified at build time). Effective order:
global → controller-level → route-level.
Configuration¶
@Value(String key, {Object? defaultValue})¶
Target: constructor parameter (of any injectable class).
Injects the configuration value at key (dot notation). The parameter type
must be String/int/double/bool/num. defaultValue must be a
String/int/double/bool literal. Without a default, a missing key
fails at startup.
@ConfigurationProperties(String prefix)¶
Target: class.
Binds a configuration section to the class: each constructor parameter is
read from <prefix>.<paramName> (nullable parameter ⇒ optional key). The
class becomes an injectable singleton. Parameter types:
String/int/double/bool/num (nullable allowed). Requires a part
directive (the binder function is generated).
Exception handling¶
@ControllerAdvice()¶
Target: class.
Declares a global exception-handling component (an injectable singleton).
Must contain at least one @ExceptionHandler method.
@ExceptionHandler(Type exception)¶
Target: method (inside a @ControllerAdvice class).
Handles thrown exceptions of exception and its subtypes. When several
handlers match, the most specific exception type wins.
Valid signatures — the first parameter type must be exactly the annotated type:
DianaResponse on(MyError e)
DianaResponse on(MyError e, DianaRequest req)
Future<DianaResponse> on(MyError e) // async also allowed
Validation¶
All validation annotations target fields of DTO classes and accept an
optional {String? message} overriding the default text. All except
@NotNull skip null values. Wrong field type ⇒ build error.
@NotNull({String? message})¶
Any field. Fails when the value is null.
@NotEmpty({String? message})¶
String, List, Set or Map. Fails when empty.
@NotBlank({String? message})¶
String. Fails when empty or whitespace-only.
@Min(num value, {String? message}) / @Max(num value, {String? message})¶
Numeric fields. Fail when < value / > value.
@Size({int? min, int? max, String? message})¶
String, List, Set or Map. Fails when the length is outside
[min, max] (either bound optional).
@Pattern(String regex, {String? message})¶
String. Fails when the value doesn't match regex. Note: in files
importing Diana, Pattern shadows dart:core's Pattern (mirroring
Jakarta's @Pattern); use an import prefix if you need the core type.
@Email({String? message})¶
String. Fails when not shaped like an email address.
@Valid()¶
A DTO field or List of DTOs. Cascades validation into the nested type,
prefixing error field names (address.street, items[2].name). The
nested type must itself have constraints.
Application¶
@DianaApplication({String configFile = 'application.yaml'})¶
Target: class (empty body by convention), anywhere under lib/.
Marks the application entrypoint — exactly one per package. The
generator emits the composition root as a sibling <file>.diana_app.dart
library containing DianaContext, buildDianaContext(),
buildDianaServer() and runDiana(). configFile is the YAML file loaded
at startup, relative to the working directory.