server library

Runtime support for Dust-generated Dart HTTP servers.

One import carries the annotations a controller needs, the extractors the generated code calls, the composition an application wires by hand, and the shelf types those touch.

import 'package:dust_server/server.dart';

@Controller('/todos', tags: ['todos'])
class TodoController with _$TodoController {
  TodoController(this._repo);

  final TodoRepo _repo;

  @GET('/{id}')
  Future<Result<Todo, NotFound>> get(
    @Extract(BearerAuth) AuthUser user,
    @Path() String id,
  ) =>
      _repo.find(user.id, id);
}

The pieces are also importable one at a time, for files that need only part of the surface:

Library Contents
annotations.dart what the generator reads
extraction.dart extractors and their interfaces
response.dart rejections, encoders, IntoResponse
router.dart the route tree and its composition
layers.dart deadlines, request ids, access records
serving.dart running and draining a server
ws.dart WebSocket routes and sessions
templating.dart rendering HTML from templates
tracing.dart spans, W3C trace context, exporters

Classes

AccessLog
Reports every served request to onRecord.
AccessRecord
One served request, as the application should record it.
AllowedOrigins
Which origins a browser may call this server from.
ApiKeyExtractable
Extracts an API key from a header, falling back to the query string.
Authorization
An Authorization header, split where the specification splits it.
BackgroundTasks
Work that outlives the response that started it.
BasicCredentials
A username and password from an Authorization: Basic header.
BasicCredentialsExtractable
Extracts and decodes an Authorization: Basic base64(user:password) header.
BearerTokenExtractable
Extracts the token from an Authorization: Bearer <token> header.
Body
Binds a parameter to the typed request body.
CatchAllSegment
{*name}: the rest of the path, captured.
Compression
Compresses responses a client said it can decompress.
ConstrainedSegment
{name|pattern}: one segment matching the caller's own pattern.
ContextExtractable<T>
Extracts a value middleware stored in the shelf request context.
Controller
Marks a class as an HTTP controller.
CookieExtractable<T>
Extracts one cookie, coerced to T.
CookieJar
The cookies one request carried.
CookieJarExtractable
Extracts every cookie at once.
Cors
Answers the cross-origin questions a browser asks before it will hand a response to JavaScript.
CurrentSpan
The span the current request is inside.
DELETE
Declares a DELETE route.
DisposableLayer
A Layer that owns something and needs telling when the server stops.
Err<T, E>
Failed operation result.
Extension<T extends Object>
Reads a value a fromExtractor layer already produced.
Extract
Binds a handler parameter to a custom extractor.
FallibleExtractable<T>
Hands the rejection to the handler instead of short-circuiting.
Field
Binds a parameter to one form field.
FirstOf<T>
Tries each extractor in order and takes the first that succeeds.
FormExtractable
Decodes an application/x-www-form-urlencoded body.
FormMap
The decoded fields of a form body.
FormUrlEncoded
Declares that the handler's body is application/x-www-form-urlencoded.
FromRequest<T>
Marks an extractor that reads the request body.
FromRequestParts<T>
Builds a T from a request, or rejects it.
GET
Declares a GET route.
Declares a HEAD route.
Binds a parameter to one header.
HeaderExtractable<T>
Extracts one header, coerced to T.
HeaderMap
Binds a parameter to the whole header map.
HeaderMapExtractable
Extracts every header as a map with lower-case keys.
HostExtractable
The host a request was addressed to.
IntoResponse
A value that can turn itself into an HTTP Response.
JsonExtractable<T>
Decodes a JSON object body into T.
JsonListExtractable<T>
Decodes a JSON array body into List<T>.
Layer
Middleware that can be written as a const expression.
LiteralSegment
Text that has to appear as written.
MatchedRouteSlot
A box a layer passes down so the router can report back what it matched.
MethodRouter
The handlers registered for one path, keyed by method.
MountedRoute
One route as it is actually served, for anything that inspects the app.
MultiPart
Declares that the handler's body is multipart/form-data.
MultipartExtractable
Decodes a multipart/form-data body.
MultipartForm
The decoded parts of a multipart/form-data body.
MultipartPart
One part of a multipart body, still arriving.
MustacheTemplates
A TemplateEngine over mustache_template.
None<T>
Option state for an absent value.
NormalizePath
Makes /todos and /todos/ mean the same thing.
Ok<T, E>
Successful operation result.
Option<T>
Optional value wrapper for Rust-style present-or-absent values.
OptionalExtractable<T>
Turns a client-error rejection into None.
OPTIONS
Declares an OPTIONS route.
ParameterSegment
{name}: one segment, captured.
Part
Binds a parameter to one multipart part.
PATCH
Declares a PATCH route.
Path
Binds a parameter to a router-captured path segment.
PathExtractable<T>
Extracts one router-captured path parameter, coerced to T.
PathSegment
One segment of a route path, after parsing.
Peer
Binds a parameter to the connection's peer information.
PeerExtractable
Extracts the connection information for this request.
PeerInfo
The peer address and port of the connection serving this request.
POST
Declares a POST route.
PUT
Declares a PUT route.
Queries
Binds a parameter to the whole query map.
QueriesExtractable<T>
Extracts every query value as a map.
Query
Binds a parameter to one query value.
QueryExtractable<T>
Extracts one query value, coerced to T.
QueryListExtractable<T>
Extracts every value for one repeated query key, coerced to T.
RawBody
Binds a parameter to the undecoded body.
RawBodyExtractable
Reads the body as raw bytes, with no media type requirement.
RawQuery
Binds a parameter to the raw, undecoded query string.
RawQueryExtractable
Extracts the raw, undecoded query string.
RecordingSpanExporter
A SpanExporter that keeps spans in a list, for tests.
Redirect
Sends the client somewhere else.
Rejection
A typed extraction failure.
Request
An HTTP request to be processed by a Shelf application.
RequestId
Gives every request an id, and echoes it back.
RequestParts
The non-body half of a request.
RequestTimeout
Gives every request below it a deadline.
Response
The response returned by a Handler.
Result<T, E>
Result of an operation that can either succeed with T or fail with E.
Route
One route in a router.
Router
A tree of routes, composed at startup.
Routes
Declares that a library's top-level handlers form a route module.
SecurityHeaders
Adds the response headers a browser uses to lock a page down.
ServerErrors
Where errors that escape a handler are reported.
ServerHandle
A running server that can be stopped without dropping work.
ServerIsolates
A cluster of isolates all serving one port.
ServerSentEvent
One server-sent event.
Service
Something that answers a request.
SessionIdExtractable
Extracts a session identifier from a cookie.
Some<T>
Option state for a present value.
Span
One timed operation inside a trace.
SpanExporter
Where finished spans go.
State
Binds a parameter to application state attached with withState.
StateExtractable<T extends Object>
Reads application state attached with Router.withState.
StreamBodyExtractable
Hands the body to the handler as an unread stream.
StreamedMultipart
A multipart body, delivered a part at a time.
StreamedMultipartExtractable
Hands a multipart/form-data body to the handler a part at a time.
TemplateEngine
Renders a named template against a set of values.
TextBodyExtractable
Reads the body as UTF-8 text.
TraceContext
The identifiers that tie one request's spans to the work it caused.
Tracing
Records one span per request, and continues an incoming trace.
Unit
Empty success value for operations that only signal completion.
UploadedFile
One decoded part of a multipart body.
ValidatedExtractable<T extends Validatable>
Runs the Validate() constraints after inner builds the value.
Verb
The shared shape of every verb annotation.
WebSocketChannel
A StreamChannel that communicates over a WebSocket.
WebSocketClose
Close codes this package uses.
WebSocketSession
One accepted WebSocket connection.

Enums

SpanStatus
How a span finished.
TrailingSlash
What to do about a trailing slash.

Extensions

OptionCombine on Option<T>
Combining Option values, and moving between Option and Result.
OptionFlatten on Option<Option<T>>
Removing one level of Option nesting.
OptionQuery on Option<T>
Reading an Option without matching on it.
OptionTransform on Option<T>
Transforming and choosing between Option values.
OptionTranspose on Option<Result<T, E>>
Swapping an Option of a Result inside out.
OptionUnzip on Option<(A, B)>
Splitting an Option of a pair.
RejectOnFailure on Result<T, Rejection>
Collapses an extraction outcome onto its value.
RequestExtraction on Request
Reading values straight off the request.
RequireExtraction on FromRequestParts<T>
Runs an extractor and throws the rejection instead of returning it.
RouterDescribe on Router
Route introspection, kept off the router's core so that serving requests and describing them stay separable.
ValidateOrReject on Validatable
Validating a value at the point a handler uses it.
ValidationRejection on ValidationResult
Turns the outcome of a Validate() derive into a rejection.

Constants

bodyLimitContextKey → const String
The context key carrying the active body limit.
defaultBodyLimit → const int
The default maximum body size, in bytes.
defaultCompressibleTypes → const Set<String>
Content types worth compressing.
defaultRevalidatedFiles → const Set<String>
Files a build regenerates without putting a content hash in their name.
matchedPathKey → const String
The context key the matched route pattern travels under.
matchedRouteSlotKey → const String
The context key a MatchedRouteSlot travels under.
pathParametersKey → const String
The context key captured path parameters travel under.
requestIdContextKey → const String
The context key a request id travels under.
unit → const Unit
Shared unit value.

Functions

any<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for any method no other handler claims.
apiKey({String header = 'x-api-key', String query = 'api_key', bool allowQuery = true}) FromRequestParts<String>
Reads an API key from a header, falling back to the query string.
basicCredentials({String realm = 'restricted'}) FromRequestParts<BasicCredentials>
Reads and decodes an Authorization: Basic header.
bearerToken() FromRequestParts<String>
Reads the token from an Authorization: Bearer header.
body<T>(T deserialize(Map<String, Object?> json)) FromRequest<T>
Decodes a JSON object body with deserialize.
bodyList<T>(T deserialize(Map<String, Object?> json)) FromRequest<List<T>>
Decodes a JSON array body with deserialize.
bodyStream() FromRequest<Stream<List<int>>>
Hands the body to the handler as an unread stream.
bytesResponse(Uint8List value, {int status = 200}) Response
Encodes value as an octet-stream response.
coerce<T>(String raw, {required String source}) Result<T, Rejection>
Converts one raw string from a path segment, query value, header, or form field into T.
compilePath(String path, {bool isMount = false}) RegExp
Compiles a route path into a matcher.
connect<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for CONNECT.
Reads one cookie, coerced to T. A nullable T makes it optional.
cookies() FromRequestParts<CookieJar>
Reads every cookie at once.
decodeRejection(Object error, {required String subject}) Rejection
The 422 for an error thrown while building a value out of subject.
delete<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for DELETE.
effectiveBodyLimit(Request request, int limit) int
The smaller of limit and whatever the router configured.
eventStream(Stream<ServerSentEvent> events, {Duration? keepAlive = const Duration(seconds: 15), int status = 200}) Response
Streams events to the client as text/event-stream.
extensionKeyFor<T>() String
The context key a value extracted by fromExtractor travels under.
fallible<T>(FromRequestParts<T> inner) FromRequestParts<Result<T, Rejection>>
Hands inner's rejection to the handler instead of short-circuiting.
firstOf<T>(List<FromRequestParts<T>> extractors) FromRequestParts<T>
Takes whichever of extractors succeeds first.
form() FromRequest<FormMap>
Decodes an application/x-www-form-urlencoded body.
fromExtractor<T extends Object>(FromRequestParts<T> extractor) Middleware
Runs extractor as middleware, and passes its value on to the handler.
get<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for GET.
groupValidationErrors(Iterable<ValidationError> errors) Map<String, List<String>>
Groups validation errors by the field they belong to, in report order.
guard(Future<Response> body()) Future<Response>
Runs body, turning a thrown Rejection into its own response and anything else into a 500 with no detail in it.
Serves endpoint for HEAD.
Reads one header, or null when it is absent.
headers() FromRequestParts<Map<String, String>>
Reads every header at once.
host() FromRequestParts<String>
Reads the Host header, which the client controls — compare, do not trust.
htmlResponse(String markup, {int status = 200}) Response
Answers with markup as an HTML document.
isJsonMediaType(String? mediaType) bool
Whether mediaType is JSON or a +json structured syntax suffix.
joinPaths(String prefix, String suffix) String
Joins two path segments, normalizing both.
jsonResponse(Object? value, {int status = 200}) Response
Encodes value as a JSON response.
matchedPathOf(Request request) String?
The route pattern that matched request, or null when none did.
multipart() FromRequest<MultipartForm>
Decodes a multipart/form-data body, buffering every part.
multipartStream({int limit = 64 * 1024 * 1024}) FromRequest<StreamedMultipart>
Hands a multipart/form-data body over a part at a time, without buffering.
nameSpan(String route) → void
Overrides the route the current span is labelled with.
noContent() Response
An empty 204 response.
normalizePrefix(String value) String
Normalizes one path segment into '' or /segment form.
optional<T>(FromRequestParts<T> inner) FromRequestParts<Option<T>>
Turns a client-error rejection from inner into None.
options<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for OPTIONS.
parameterNames(String path) List<String>
The parameter names a route path declares, in order.
patch<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for PATCH.
path<T>(String name) FromRequestParts<T>
Reads the {name} path segment, coerced to T.
pathParametersOf(Request request) Map<String, String>
Reads router-captured path parameters from request.
peer() FromRequestParts<PeerInfo>
The connection's peer address and port.
post<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for POST.
put<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for PUT.
queries() FromRequestParts<Map<String, String>>
Reads every query pair at once.
query<T>(String name) FromRequestParts<T>
Reads one query value, coerced to T. A nullable T makes it optional.
queryList<T>(String name) FromRequestParts<List<T>>
Reads every value of a repeated query key, coerced to T.
rawBody() FromRequest<Uint8List>
Reads the body as raw bytes.
rawQuery() FromRequestParts<String?>
Reads the raw, undecoded query string, or null when there is none.
rawRequest() FromRequestParts<Request>
The request itself, for a handler that wants to reach past the extractors.
readBody(Request request, {int limit = defaultBodyLimit}) Future<Result<Uint8List, Rejection>>
Reads the whole request body, rejecting with 413 past limit.
readsRequestBody(FromRequestParts<Object?> extractor) bool
Whether extractor ends up reading the request body.
render(TemplateEngine engine, String template, Map<String, Object?> values, {int status = 200}) Response
Renders template with values and answers with the result.
reportMatchedRoute(Request request, String route) → void
Fills the slot request carries, when it carries one.
requestIdOf(Request request) String?
The id given to this request, or null when no RequestId layer ran.
resolveMiddleware(List<Object> entries) List<Middleware>
Turns a mixed list of Layer and shelf Middleware values into shelf middleware, keeping the order they were written in.
responseFrom(Object? value, {int status = 200}) Response
Turns whatever a typed handler returned into a response.
serve(Router router, InternetAddress address, int port, {SecurityContext? securityContext, bool shared = false, BackgroundTasks? background}) Future<ServerHandle>
Serves router, counting requests so shutdown can wait for them.
serveIsolates(RouterFactory factory, InternetAddress address, int port, {required int isolates, void onIsolateError(Object? error, Object? stackTrace)?}) Future<ServerIsolates>
Serves factory from isolates isolates, all sharing one port.
sessionId({String name = 'session'}) FromRequestParts<String>
Reads a session identifier from a cookie.
singlePageApp(String file) Handler
Serves one file for every document request, for a single-page application.
state<T extends Object>() FromRequestParts<T>
Reads the application state of type T attached with withState.
stateKeyFor<T>() String
The request-context key state of type T travels under.
stateMiddleware(Map<String, Object> state) Middleware?
Builds the middleware that puts state on every request below a group.
staticFiles(String directory, {bool html = false, String? defaultDocument = 'index.html', Set<String> revalidate = defaultRevalidatedFiles, Duration immutableFor = const Duration(days: 365), bool crossOriginIsolated = false, bool listDirectories = false, bool serveFilesOutsidePath = false}) Handler
Serves the files under directory.
streamed(Stream<List<int>> body, {int status = 200, String contentType = 'application/octet-stream', Map<String, String> headers = const {}}) Response
Answers with body as it arrives, without buffering it.
streamResponse(Stream<List<int>> value, {int status = 200}) Response
Streams value as an octet-stream response.
textBody() FromRequest<String>
Reads the body as UTF-8 text.
textResponse(String value, {int status = 200}) Response
Encodes value as a plain-text response.
trace<T>(Endpoint<T> endpoint, {int status = 200}) MethodRouter
Serves endpoint for TRACE.
typeOf<X>() Type
Reifies X so nullable targets can be compared, since T == String? is not valid syntax.
valid<T extends Validatable>(FromRequestParts<T> inner) FromRequestParts<T>
Runs the generated validate after inner builds the value.
ws(WebSocketHandler handler, {Iterable<String>? protocols, Duration? pingInterval}) MethodRouter
Serves a WebSocket upgrade at this path.

Typedefs

Endpoint<T> = FutureOr<T> Function(Request request)
What a verb builder accepts: a function of the request that returns whatever the endpoint produced.
Handler = FutureOr<Response> Function(Request request)
A function which handles a Request.
Middleware = Handler Function(Handler innerHandler)
A function which creates a new Handler by wrapping a Handler.
RouterFactory = Router Function()
Builds the application for one isolate.
WebSocketHandler = FutureOr<void> Function(WebSocketSession session)
What a WebSocket route runs once the connection is open.

Exceptions / Errors

TemplateNotFound
A template nobody registered.