diana library

Diana — a Spring-inspired backend framework for Dart.

Annotation-driven controllers, compile-time dependency injection, middleware, configuration and validation over a high-performance HTTP engine. See package:diana_annotation for the annotation set (re-exported here).

Classes

BaseWebSocketHandler
Convenience base class with no-op implementations of every callback.
BinaryMessage
A binary frame.
Body
Binds a route-method parameter to the JSON request body.
BodyCodec
Translates one wire format to/from Map<String, dynamic>/List/scalars.
BodyCodecRegistry
Looks up codecs by MIME type. Always contains JsonBodyCodec.
Cacheable
Caches the method's result per argument list, in memory, per isolate (Spring's @Cacheable).
CacheSpec
Per-method cache configuration handed to a DianaCacheStore.
CircuitBreaker
Fails fast when the method keeps failing (spring-retry's @CircuitBreaker).
CircuitBreakerPolicy
Circuit breaker (@CircuitBreaker): closed → open after failureThreshold consecutive failed calls; while open, run throws CircuitOpenException without invoking the call; after resetTimeout one half-open trial is allowed — success closes the circuit, failure re-opens it. State is per instance (one per proxied method), per isolate. Named CircuitBreakerPolicy because package:diana re-exports the CircuitBreaker annotation.
Component
A generic Injectable component (semantic alias).
ConfigurationProperties
Binds a whole configuration section to a class, which becomes injectable.
Consumes
Restricts the request content types a route (or every route of a controller) accepts. The body is decoded with the matching registered BodyCodec; other content types get a 415. Method-level replaces controller-level entirely; without the annotation, JSON is used.
ControllerAdvice
Marks a class as a global exception-handling component.
CorsPolicy
CronExpression
A parsed cron expression. Build with CronExpression.parse; query the next fire time with nextAfter.
CrossOrigin
Enables CORS for a controller (all routes) or a single route, replacing the global server.cors.* policy entirely (route wins over controller, controller over global — no field merging).
Delete
Maps a method to DELETE requests.
DianaApplication
Marks the application entrypoint class.
DianaCacheStore
Pluggable @Cacheable backend: declare exactly one singleton provider extending this and every cached method routes through it instead of the built-in per-proxy MethodCache.
DianaConfig
Configuration store backed by flattened dot-separated keys, with environment-variable overrides.
DianaEventBus
The event bus behind DianaEventPublisher.
DianaEventPublisher
Publishes application events to @EventListener methods.
DianaObserver
DianaRequest
Diana's view of an incoming HTTP request.
DianaRequestLimits
Per-request limits, configured on the server and consulted by binding helpers (generated code never touches configuration).
DianaResponse
Diana's HTTP response.
DianaRunnable
What the generated bootstrap hands to DianaRuntime.run: the server plus the application lifecycle callbacks (and the event bus, when the app declares @EventListener methods or injects DianaEventPublisher).
DianaRuntime
Runs a Diana application with lifecycle and graceful shutdown: bootstrap → initialize() (@PostConstruct in dependency order) → serve() → wait for SIGINT/SIGTERM → close() (drains in-flight requests) → dispose() (@PreDestroy in reverse order).
DianaScheduler
Schedules and runs recurring tasks.
DianaServer
Diana's HTTP server: routes registered by generated code, composed with middleware and the exception boundary, served over the HTTP engine.
Email
Constrains a String field to look like an email address.
EventListener
Marks a method as an application-event listener (Spring: @EventListener).
ExceptionHandler
Handles exceptions of type exception (and its subtypes) thrown by any route.
FieldError
One field-level validation failure.
FormData
Decoded form body: text fields plus uploaded files.
Get
Maps a method to GET requests.
GlobalMiddleware
Registers a Middleware implementation globally, applied to every route.
GrpcService
Registers a class extending a protoc-generated XServiceBase (package:grpc's Service) as a gRPC service.
Binds a route-method parameter to an HTTP request header.
HealthIndicator
Contributes a component to /actuator/health. Implementations are discovered through the DI graph and must be singletons.
HealthStatus
HttpRoute
Base class for HTTP route annotations. Prefer the Get/Post/Put/ Delete/Patch shorthands.
Injectable
Marks a class as a provider in the dependency injection graph.
InMemoryCacheStore
The per-isolate default, exposed for stores that decorate it (logging, metrics, fallbacks): one MethodCache per CacheSpec.method, with the same semantics as the built-in backend — TTL + LRU, single-flight, errors never cached.
Json
Generates fromJson/toJson for this class — no boilerplate needed.
JsonBodyCodec
The built-in JSON codec (also accepts …+json content types).
JsonField
Customizes the JSON key of a field inside a @Json class.
Max
Constrains a numeric field to be <= value.
MessageMapping
Handles STOMP messages sent to a destination under the app prefix (stomp.appPrefix, default /app) — Spring's @MessageMapping.
MethodCache<V>
Per-method TTL + LRU cache, per isolate (@Cacheable).
Middleware
Spring-style interceptor around request handling.
Min
Constrains a numeric field to be >= value.
Named
Selects a qualified provider for a constructor parameter.
NotBlank
Constrains a String field to contain at least one non-whitespace character.
NotEmpty
Constrains a String, List or Map field to be non-empty.
NotNull
Constrains a field to be non-null. All other constraints skip null values, so combine them with NotNull (or a non-nullable type) when the field is required.
Patch
Maps a method to PATCH requests.
PathParam
Binds a route-method parameter to a path parameter.
Pattern
Constrains a String field to fully match a regular expression.
Post
Maps a method to POST requests.
PostConstruct
Marks a method to run after the provider is constructed, during application initialization (Spring: @PostConstruct).
PreDestroy
Marks a method to run during graceful shutdown (Spring: @PreDestroy).
Principal
Binds the authenticated principal to a route-method parameter (Spring: @AuthenticationPrincipal).
Produces
Declares the response content types a route (or controller) can produce. The response is encoded with the first type the request's Accept header allows (server preference order); nothing acceptable → 406. Method-level replaces controller-level; without the annotation, JSON.
Put
Maps a method to PUT requests.
QueryParam
Binds a route-method parameter to a query-string parameter.
Repository
An Injectable that encapsulates data access (semantic alias).
ResponseStatus
Overrides the success status code of a route (default 200, or 204 for void returns).
RestController
Marks a class as an HTTP controller whose routes are mounted under path.
Retryable
Retries the method with a fixed backoff when it throws (spring-retry's @Retryable).
RetryPolicy
Fixed-backoff retry with optional exception filtering (@Retryable).
RolesAllowed
Requires an authenticated principal holding any of roles (JSR-250 semantics). Implies Secured: anonymous → 401, authenticated but missing every role → 403.
Scheduled
Runs a method on a fixed schedule (Spring: @Scheduled), started after application initialization and stopped during graceful shutdown.
Secured
Requires an authenticated principal to access the route(s).
SendTo
Publishes a @MessageMapping method's return value to a broker destination (Spring's @SendTo).
ServerSentEvent
One event of an SSE stream.
Service
An Injectable that expresses business logic (semantic alias).
Size
Constrains the length of a String, List or Map field.
StompBroker
The in-memory STOMP broker.
StompEndpoint
Base class for a STOMP endpoint: a singleton @WebSocketController that delegates every WebSocket callback to the injected StompBroker.
StompFrame
One STOMP frame: canonical upper-case command, first-occurrence-wins unescaped headers, and the UTF-8 body.
StompMessage
The context passed to a @MessageMapping handler (optional 2nd param).
StompPublisher
Publishes messages to STOMP destinations. Inject it into any provider to push to subscribers from server-side code.
StompRelayEvent
Cross-isolate relay envelope — plain sendable data broadcast through the event bus so subscribers on other isolates receive the message.
Table
Maps a @Json entity class to a database table for Diana query repositories (DianaRepository in the diana_data package).
TextMessage
A text frame.
Timed
Records the method's invocation duration and outcome as metrics (and a trace span) via the app's observability provider (Micrometer's @Timed).
Transactional
Runs the method inside a database transaction (Spring: @Transactional).
UploadedFile
One uploaded file from a multipart form.
UseMiddleware
Applies Middleware implementations to a controller (all its routes) or to a single route method, in the listed order.
Valid
Cascades validation into a nested DTO field (or a List of DTOs).
ValidationResult
Validator<T>
Validates instances of T. Implementations are generated from constraint annotations on DTO fields.
Value
Injects a configuration value (from application.yaml, overridable via environment variables) into a constructor parameter.
WebSocketController
Registers a class implementing Diana's WebSocketHandler interface as a WebSocket endpoint at path (Spring: a WebSocketHandler registered through WebSocketConfigurer).
WebSocketHandler
Lifecycle of a WebSocket endpoint (Spring: WebSocketHandler).
WebSocketMessage
A message received from the peer.
WebSocketSession
One live WebSocket connection (Spring: WebSocketSession).
XmlCodec

Enums

HttpMethod
HTTP methods supported by Diana routes.
Scope
Lifecycle scope of an injectable class.

Constants

principalAttributeKey → const String
Request attribute under which authentication middleware stores the authenticated principal. A stable cross-package contract: written by package:diana_auth's AuthenticationMiddleware (which imports this constant) and read by bindPrincipal in generated adapters.
stompHeartbeat → const String
A bare EOL — the STOMP heartbeat unit.

Functions

acceptsMime(String acceptHeader, String mime) → bool
Whether acceptHeader accepts mime (type/subtype).
bindHeader<T>(DianaRequest request, String name) → T
Binds a request header (case-insensitive). Nullable T makes it optional.
bindPathParam<T>(DianaRequest request, String name) → T
Binds a path parameter. Path parameters always exist when the route matched, so T should be non-nullable.
bindPrincipal<T>(DianaRequest request) → T
Binds the authenticated principal for a @Principal() parameter.
bindQueryParam<T>(DianaRequest request, String name, {String? defaultValue}) → T
Binds a query parameter. Nullable T makes it optional; defaultValue (as written in the query string) is used when absent.
checkEmail(String? value, String field, List<FieldError> errors, {String? message}) → void
checkMax(num? value, num max, String field, List<FieldError> errors, {String? message}) → void
checkMin(num? value, num min, String field, List<FieldError> errors, {String? message}) → void
checkNotBlank(String? value, String field, List<FieldError> errors, {String? message}) → void
checkNotEmpty(Object? value, String field, List<FieldError> errors, {String? message}) → void
checkNotNull(Object? value, String field, List<FieldError> errors, {String? message}) → void
checkPattern(String? value, String regex, String field, List<FieldError> errors, {String? message}) → void
checkSize(Object? value, String field, List<FieldError> errors, {int? min, int? max, String? message}) → void
composeMiddleware(List<Middleware> middleware, DianaHandler handler) → DianaHandler
Folds middleware around handler, outermost first: the first element sees the request first and the response last.
corsPreflightHandler(Map<HttpMethod, CorsPolicy> policies) → DianaHandler
Builds the OPTIONS preflight handler for one path, given the CORS-enabled methods registered on it.
decodeDto<T>(T decode()) → T
Runs a DTO decode (decode wraps fromJson/generated codecs) and turns shape mismatches (TypeError, FormatException, enum ArgumentError) into 400s instead of 500s.
decodeFormBody(DianaRequest request) → Future<FormData>
Decodes a multipart/form-data or application/x-www-form-urlencoded body. Any other content type is a 415; a multipart body larger than request.limits.multipartMaxBytes is a 413 (the raw stream — including part headers and boundaries — is capped by DianaRequest.readBodyAsBytes; the per-part sum below is a second, decoded-content check). Urlencoded bodies are capped at request.limits.maxBodyBytes by the string read.
decodeJsonListBody(DianaRequest request) → Future<List>
Decodes the request body as a JSON array.
decodeJsonMapBody(DianaRequest request) → Future<Map<String, dynamic>>
Decodes the request body as a JSON object.
decodeListBody(DianaRequest request, {required List<String> consumes}) → Future<List>
Decodes the request body as an array using the codec matching its content type, restricted to consumes.
decodeMapBody(DianaRequest request, {required List<String> consumes}) → Future<Map<String, dynamic>>
Decodes the request body as an object using the codec matching its content type, restricted to consumes.
encodeSse(Stream<ServerSentEvent> events, {int heartbeatSeconds = 0}) → Stream<List<int>>
Encodes events into the text/event-stream wire format. A positive heartbeatSeconds interleaves comment lines (: keep-alive) so proxies keep the connection open — and so a dead client is detected on the next write.
encodeSseEvent(ServerSentEvent event) → String
Frames a single event per the SSE specification.
healthEndpointHandler(List<HealthIndicator> indicators) → DianaHandler
Aggregating /actuator/health handler: overall DOWN (HTTP 503) when any indicator is down; indicator exceptions count as down.
infoEndpointHandler(DianaConfig config) → DianaHandler
/actuator/info handler: serves the info.* configuration section, re-nested (info.build.rev → {"build": {"rev": ...}}).
livenessEndpointHandler() → DianaHandler
/actuator/health/liveness handler: a trivial 200 UP — the process is running and serving. Kubernetes restarts the pod when this fails, so it deliberately does not consult dependencies.
mergeNested(ValidationResult nested, String prefix, List<FieldError> errors) → void
Merges the nested result of a cascaded (@Valid) field into errors, prefixing field names (address.street, items[2].name).
negotiatedResponse(DianaRequest request, Object? payload, {required List<String> produces, int statusCode = 200}) → DianaResponse
Encodes payload with the first codec of produces the request's Accept header allows (server preference order). 406 when nothing in produces is acceptable, 500-shaped error when a produced type has no codec (a build-time-declared mime should always have one at runtime).
parseStompChunk(List<int> bytes) → List<StompFrame>
Byte-level variant of parseStompText (also used for binary WS frames).
parseStompText(String text) → List<StompFrame>
Parses one WebSocket text message into zero or more frames (heartbeat EOLs between and around frames are consumed silently).
patchOpenApiInfo(String document, DianaConfig config) → String
Patches info.title/info.version of the build-time-generated document from server.openapi.title / server.openapi.version (keeping the const deterministic while letting deployments brand it).
readinessEndpointHandler(List<HealthIndicator> indicators) → DianaHandler
/actuator/health/readiness handler: aggregates indicators like /actuator/health (503 when any is down). Kubernetes stops routing traffic to the pod when this fails, without restarting it.
runTimed<T>(DianaObserver? observer, String name, Future<T> run()) → Future<T>
@Timed glue: with no observer the call is a zero-cost passthrough (@Timed is a silent no-op without an observability provider).
serializeStompFrame(StompFrame frame) → String
Serializes frame to wire text. Headers of CONNECTED (and the other connect-family frames) are emitted unescaped, everything else escaped.
sseResponse(DianaRequest request, Stream<ServerSentEvent> events) → DianaResponse
Builds the streaming SSE response for events: 200, text/event-stream, cache-control: no-cache, heartbeat from request.limits.sseHeartbeatSeconds.
stompJsonBody(Map<String, dynamic> json) → String
Encodes a @MessageMapping DTO reply body.
stompJsonMap(String body) → Map<String, dynamic>
Decodes a JSON object body for a @MessageMapping DTO payload.
withCors(CorsPolicy policy, DianaHandler inner) → DianaHandler
Wraps inner to add CORS headers to actual (non-preflight) responses.
withErrorBoundary(DianaHandler handler, {ExceptionMapper? mapper, void onUnhandled(Object error, StackTrace stackTrace)?}) → DianaHandler
Wraps handler in Diana's exception boundary.

Typedefs

DianaHandler = FutureOr<DianaResponse> Function(DianaRequest request)
A request handler: the composed unit of Diana's pipeline.
ExceptionMapper = FutureOr<DianaResponse?> Function(Object error, StackTrace stackTrace, DianaRequest request)
Maps an exception to a response, or null to fall through to Diana's built-in handling. Implemented by generated @ControllerAdvice chains.
Next = FutureOr<DianaResponse> Function(DianaRequest request)
Continuation passed to Middleware.handle.
WebSocketHandlerFactory = FutureOr<WebSocketHandler> Function()
Produces the handler for a new connection. Generated code passes () => ctx.handler for shared (singleton) handlers and () => ctx.createHandler() for per-connection (transient) handlers.

Exceptions / Errors

BadRequestException
CircuitOpenException
Thrown by CircuitBreakerPolicy.run while the circuit is open. Maps to an opaque 500 by default; use a @ControllerAdvice to translate it (e.g. into a 503).
ConfigException
Thrown for missing or badly-typed configuration values.
ConflictException
ForbiddenException
HttpException
Diana's HTTP exception hierarchy.
InternalServerErrorException
NotAcceptableException
NotFoundException
PayloadTooLargeException
StompParseException
Thrown for malformed input; the message becomes the ERROR frame's message: header.
StompPayloadException
Thrown when a @MessageMapping payload cannot be decoded; surfaces as an ERROR frame to the offending client.
UnauthorizedException
UnprocessableEntityException
UnsupportedMediaTypeException
ValidationException
Thrown when DTO validation fails; mapped to a structured 400 response: {"error": "validation_failed", "fields": {"title": ["..."], ...}}.