wowRoutes

fun wowRoutes(manifest: Manifest, gateway: CommandGateway, reads: StateReads = StateReads.NONE, callerResolver: CallerResolver = CallerResolver.ANONYMOUS, options: WowHttpOptions = WowHttpOptions(), queries: HttpQueries = HttpQueries.NONE, masks: PayloadMasks = PayloadMasks(manifest), scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default), routes: ServiceRoutes = ServiceRoutes.NONE): RouterFunction<ServerResponse>

The routes of the public port (.2; –), materialized from manifest alone:

  • every route of every command (CommandManifest.routes) sends that command through gateway: a command a transformer finds the aggregate of (@Unaddressed, or mounted) has its route without an id there, as the compiler writes it. The system commands are among them, routed as the Manifest says (systemTarget): the lifecycle commands an aggregate lists, its snapshot rebuild, and the job commands of its context. An internal command's routes (@InternalCommand, CommandManifest.internal) are not served here but on the internal port (callRoutes): a request to one is the 404 problem of any unknown path, which does not say the command exists;

  • GET /{context}/{aggregate}/{id}/state, ?version=, ?at= and GET …/{id}/state/trace read reads, and GET /{context}/{aggregate}/state and …/state/trace the caller's own aggregate of one whose id is its owner's, in the tenant the gateway's tenants decide, as for a command; each state and each event of a trace masked as a snapshot query masks it, by the snapshot query gateway of queries or, without one, by masks;

  • POST /{context}/{aggregate}/{model}/query and its GET query the models of AggregateManifest.queries that queries serves, the snapshots and the events of each aggregate type;

  • POST /wow/dataset/{context}/{dataset}/query and its GET query the datasets of queries as a snapshot model is queried, and GET /wow/dataset lists those the caller sees; a dataset that joins or leaves while the node runs is served or not from then on;

  • GET /wow/manifest answers manifest without the JVM class names of its schemas (withoutClassNames), which the internal port's keeps, unless WowHttpOptions.manifestEndpoint is off;

  • GET /wow/openapi answers the OpenAPI 3.1 document of these routes (openApiOf,.2), the internal commands left out, unless WowHttpOptions.openApiEndpoint is off;

  • any other request under a context of the Manifest is a 404 problem.

Every route is authenticated by callerResolver (401 wow.auth.unauthenticated when it returns null). A command request that carries Wow-Call is refused (403 wow.auth.forbidden) whatever its credential: the services' synchronous calls are taken on the internal port alone (callRoutes). So is a system command of a built-in aggregate, a job's or the snapshot rebuild's, on a node without an authorizer (CommandGateway.authorizes): never allowed by default, it needs an authorizer that allows it. Errors are RFC 9457 problems whose statuses come from the Manifest's error tables (ErrorStatuses). A context's service routes (ServiceRoutes) are mounted from the Manifest too, each with the handler its module binds: a route without one, or a handler of no route, fails here, so the node does not start. The host serves other routes under a context's path only by composing them before these.

The streamed answers (text/event-stream) are produced in scope, apart from their requests: the host passes one it cancels as the node stops, so no producer outlives the node.