Package-level declarations

Types

Link copied to clipboard
annotation class Access(val name: String = "")

Marks a member of an aggregate's state as one of the aggregate's access attributes: a fact of the state that decides who may read and change the aggregate, which the service's access policies compare with the caller's claims.

Link copied to clipboard
annotation class AfterCommand(val include: Array<KClass<*>> = [], val exclude: Array<KClass<*>> = [])

A function of an AggregateRoot that runs after its command functions: it sees the state the command function saw, not yet evolved by its events, and returns events appended after them in the same stream. It does not run when the command is rejected. A function named afterCommand needs no annotation.

Link copied to clipboard

The property of a command that holds the id of the aggregate the command acts on, its target: a String the command's class declares, or an interface it implements does, stored or computed from other properties. The compiler generates its read, and the Manifest names it (idProperty), so:

Link copied to clipboard
annotation class AggregateRoot(val lifecycle: Array<KClass<*>> = [ DeleteAggregate::class, RestoreAggregate::class, TransferOwner::class, TransferSpace::class, ], val published: Boolean = true, val publishState: Boolean = true, val topic: String = "", val ownership: Ownership = Ownership.OWNER, val idSource: AggregateIdSource = AggregateIdSource.ASSIGNED, val snapshot: Boolean = true, val stateRevision: Int = 1, val retiredEvents: Array<String> = [])

An aggregate root: the compiler turns it into an aggregate model, with its command functions (OnCommand or named onCommand), its state's sourcing functions (OnSourcing or named onSourcing) and its AfterCommand hooks. The aggregate is named by its Name, or by its simple name in snake_case.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.CLASS])
annotation class Alias(vararg val value: String)

Former names of a command or event type.

Link copied to clipboard

A command that may also create its aggregate: it is accepted whether or not the aggregate exists.

Link copied to clipboard
annotation class Blocking

A function that blocks its thread, such as one writing a projection or checking a uniqueness over JDBC. A synchronous function is otherwise taken for pure computation and runs inline on a shared worker; the generated call runs this one on the blocking dispatcher, a virtual thread per call. It applies to command functions (@OnCommand), after hooks (@AfterCommand), subscription handlers (@OnEvent, @OnRejected, @OnCommitted) and scheduled jobs (@OnSchedule), also when it is on the function an override overrides. Sourcing functions, @Upgrade functions and @Access members do no I/O, so it is a compile error on them; on a function returning a Reactor publisher it is a warning, since a publisher should not block.

Link copied to clipboard
annotation class BoundedContext(val name: String, val description: String = "")

The bounded context a domain module belongs to. The runtime binds the context when it assembles the Manifest fragments, so a module rarely carries it; when it does, its name and description go into the Manifest.

Link copied to clipboard

A command that creates its aggregate: it is accepted only while the aggregate does not exist yet.

Link copied to clipboard

A description of a type or a field, carried into the Manifest and the documentation generated from it.

Link copied to clipboard
annotation class ErrorCode(val description: String = "", val status: Int = 422)

A rejection code of the domain, on a const val of type String, top-level or in an object, that holds the code a command function rejects with (Decision.reject(code, message)). The compiler lists the codes of its module in the context's errors of the Manifest fragment, with status and description. In Java it goes on a static final String field.

Link copied to clipboard
annotation class InternalCommand

A command only the platform sends: the service's own sagas, schedules and in-process gateway, and the other services that call it on its internal port, as wow.callers.<service> permits them. The Manifest lists it as internal, with its routes as for any command; the internal port serves them, and the public port does not: a request to one of them there is answered as an unknown path is, a 404 problem. The public port's OpenAPI document and the clients wow-generator generates leave it out.

Link copied to clipboard
annotation class MountedCommand(val aggregate: String, val transformsTo: Array<KClass<*>> = [])

A command mounted under an aggregate's routes that no aggregate decides: it has no @OnCommand, and exactly one CommandTransformer of the service claims it, turning it into a command an aggregate decides, such as an import that becomes the aggregate's creation command or an external callback in a provider's shape. The Manifest lists it under aggregate as a mounted command, with its routes (with and without an aggregate id), and the service refuses to start when no transformer, or more than one, claims it.

Link copied to clipboard

The name of an aggregate, a processor, a command or an event, in place of the one derived from the class's simple name. Commands and events are typed context.aggregate.Name.

Link copied to clipboard
annotation class OnCommand(val produces: Array<KClass<*>> = [], val schedules: Array<KClass<*>> = [], val onDeleted: Boolean = false)

A command function of an AggregateRoot: it takes the command, or a Command of it, and decides the events. A function named onCommand needs no annotation, but only the annotation declares produces.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.FUNCTION])
annotation class OnCommitted

A handler of a Saga for the success receipt of a command the saga derived, the counterpart of OnRejected: it takes a me.ahoo.wow.api.subscribe.CommandReceipt.Committed of the command's type (or of *, for every command the saga derives) and, optionally, the SagaContext (or the SubscriptionContext it extends), and returns the commands it derives in turn, as an OnEvent handler of a saga does.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.FUNCTION])
annotation class OnEvent(val aggregates: Array<String> = [], val start: OnEvent.Start = Start.DEFAULT)

An event handler of a Projection, Reactor or Saga: it takes a me.ahoo.wow.api.subscribe.StateEvent and, optionally, the processor's context: a projection's or a reactor's SubscriptionContext, a saga's SagaContext or the SubscriptionContext it extends. A saga's handler declares what it sends with Sends. Each handler is its own subscription, named processor.function, or processor.name with its Name. Only this annotation declares a handler, whatever the function's name.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.FUNCTION])
annotation class OnRejected

A handler of a Saga for the rejection of a command the saga derived or called: it takes a me.ahoo.wow.api.subscribe.CommandReceipt.Rejected of the command's type (or of *, for every command the saga sends) and, optionally, the SagaContext (or the SubscriptionContext it extends), and returns the commands that compensate, as an OnEvent handler of a saga does. A rejection is a business outcome: the runtime hands it here instead of parking the aggregate, whether the command was rejected in the saga's own context or in another, whose receipt comes back, and whether the handler derived it or called it (SagaContext.call) and let its rejection through.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.FUNCTION])
annotation class OnSchedule(val name: String, val cron: String, val zone: String = ScheduleRule.UTC, val scope: JobScope = JobScope.SYSTEM, val misfire: Misfire = Misfire.COALESCE)

A job of a Saga run by a cron rule: the handler takes a me.ahoo.wow.api.schedule.ScheduleTick and, optionally, the SagaContext (or the SubscriptionContext it extends), and returns the commands it derives, as an @OnEvent handler of a saga does. The compiler writes the job into the Manifest. Each job is kept by the built-in aggregate <context>.schedule, whose id is the job's name in its tenant: each time the rule is due it commits Ticked(slot), and its subscription, processor.function, hands the ticks of the job's instances, and of no other job's, to the handler, retried and parked as any subscription's.

Link copied to clipboard

A sourcing function of an aggregate's state: it applies one event to the state. A function named onSourcing needs no annotation.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.CLASS])
annotation class Projection

A projection: a processor whose OnEvent functions write a read model from committed events.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.CLASS])
annotation class Reactor

A reactor: a processor whose OnEvent functions act on committed events, such as sending a notification or calling another system. It replaces 9.x's @EventProcessor.

Link copied to clipboard
annotation class Retry(val maxAttempts: Int = 0, val initialBackoff: String = "", val maxBackoff: String = "", val multiplier: Double = 0.0, val timeout: String = "", val recoverable: Array<KClass<out Throwable>> = [], val unrecoverable: Array<KClass<out Throwable>> = [], val systemic: Array<KClass<out Throwable>> = [])

The in-process retry budget of a subscription handler (in place of 9.x @Retry): how often a failing call is attempted, how long it waits between attempts, and how long one attempt may run, before the aggregate is parked in the failure ledger. A Projection, Reactor or Saga class carries it for all its OnEvent handlers, and a saga's for its OnSchedule handlers too; a handler's own overrides it, setting by setting. It is inherited: a processor class without one runs under its nearest superclass's, taken whole, and a handler function without one under the one on the function it overrides. An interface carries none: a processor that implements an interface annotated @Retry is a compile error. A saga's OnRejected and OnCommitted handlers take none: a receipt of the saga's own context is handled under the budget of the OnEvent handler that derived the command, one from another context under the host's retry of the context's receipts subscription, wow.receipts.<context>.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.CLASS])
annotation class Revision(val value: Int)

The revision of a domain event's schema. An event without it is at revision 1.

Link copied to clipboard

The HTTP method of a ServiceRoute.

Link copied to clipboard
annotation class RouteQuery(val name: String = "")

A parameter of a ServiceRoute bound to the query parameter of its name, or name: optional when the parameter is nullable, required otherwise.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.CLASS])
annotation class Saga

A saga: a processor whose OnEvent functions derive commands from committed events. It replaces 9.x's @StatelessSaga, and compensation that 9.x wrote with @OnError is written as a saga.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.FUNCTION])
annotation class Sends(val derives: Array<KClass<*>> = [], val schedules: Array<KClass<*>> = [], val calls: Array<KClass<*>> = [])

What a Saga's handler sends, by the commands' classes: any of its handlers, @OnEvent, @OnRejected, @OnCommitted or @OnSchedule, may carry it, and nothing else does: the compiler refuses it on a Projection's or a Reactor's handler, or on a function that is no handler. Each class is a command class of this context or of another (from that context's api), or a sealed type, which stands for its concrete subclasses; the service's build fails on a class that neither this context nor a peer contract on its class path decides. The compiler writes them into the Manifest, and the runtime holds the handler to them: sending a command of a class it does not declare fails the handling, which no retry changes (unrecoverable), so the aggregate parks at once.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.FUNCTION])
annotation class ServiceRoute(val method: RouteMethod, val path: String, val name: String = "", val errors: Array<String> = [])

A service route: an HTTP route of the module's bounded context whose handler is this function, not a command or a query. The model processor lists it in the context's Manifest (routes), with its parameters and the schemas of its request and response, and generates its binding; the edge mounts it from the Manifest and admits its caller as it admits a query's, so it is a route of the service's contract like any other.

Link copied to clipboard

A one-line summary of a type or a field, carried into the Manifest and the documentation generated from it.

Link copied to clipboard

A command whose request may name no aggregate: a CommandTransformer of the service finds the aggregate it acts on, such as one whose id the server derives from the caller and the body. The Manifest lists its route without an aggregate id (POST /{context}/{aggregate}/{command}) beside the one with, as it does for a command that creates its aggregate, so the clients generated from it have both. Without a transformer that finds an aggregate, a request that names none is refused (wow.aggregate.not-found).

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.FUNCTION])
annotation class Upgrade(val event: KClass<*>, val from: Int)

An upgrade of a domain event's stored JSON from revision from to revision from + 1. An event at Revision n needs one upgrade from each of the revisions 1 to n - 1: the model processor chains them, and a gap, a duplicate, an upgrade from 0 or less or from the current revision or beyond, or one of a class that is not an event of an aggregate in the module, is a compile error.