Skip to content
Ocean-Atlasv0.1.0Canonical Knowledge

Service DSL Reference

The @service section defines deployable Ocean units.

A service composes domain behavior and connects it to system interfaces and infrastructure. It can implement or consume APIs, use brokers and databases, orchestrate components and FSMs, use expressions and functions, bind configuration and context, expose vault-backed secrets, initialize behavior, aggregate results, and declare typed connections.

The service is the bridge between abstract domain behavior and runnable system integration.


A service owns orchestration and deployment-facing integration—not the internal state of domain behavior.

APIs ─────────┐
Brokers ──────┤
Databases ────┤
Config ───────┼── Service ── Components / FSMs / Expressions
Context ──────┤
Vaults ───────┤
Functions ────┘

Components own composition, FSMs own behavioral state, and expressions own stateless logic. The service connects these capabilities into a deployable boundary.


@service
<ServiceName>
port: <port1>, <port2>, ...
use config <ConfigName> as <alias>
use context <ContextName> as <alias>
use api <ApiName> [as <alias>]
impl api <ApiName> [as <alias>] on <port-or-config-path>
use broker <BrokerName> as <alias>
use database <DatabaseName> [as <alias>]
use expression <ExpressionName> [as <alias>]
use fsm <FSMName> as <alias>
use component <ComponentName> [as <alias>]
use function <FunctionName> [as <alias>]
use vault <VaultName> [as <alias>]
init <expression-or-function-call>
aggregate <aggregation>
connect <source> -> <target>

A file may define multiple services.


Service names follow the Ocean type-name convention and must be unique within the resolved service scope.

Examples:

OrderService
InventoryService
PaymentOrchestrator

A service name identifies the deployable model unit; target-specific deployment names may be derived separately.


Ports are declared as a comma-separated list:

port: rest, admin

Ports provide symbolic binding points for implemented APIs.

An implemented API selects a port using on:

impl api PublicAPI as publicApi on rest

A port may also be resolved from configuration:

impl api AdminAPI as adminApi on cfg.ports.adminPort

Port symbols and configuration paths must resolve unambiguously.


Services bring model elements into local scope through injection declarations.

use declares a dependency consumed by the service.

impl api declares an API contract fulfilled by the service.

use api → service calls or depends on an API
impl api → service exposes and fulfills an API

Aliases provide the local identity used in connections and calls.


use api PartnerAPI

or:

use api PartnerAPI as partner

A used API represents an outbound dependency. Its operations may be referenced through the local alias or available name according to alias-resolution rules.

use api does not bind a listening port.


impl api OrderAPI as api on rest

impl api declares that the service fulfills the named API contract. The on <port> clause is required.

The target may be:

  • a port declared by port:;
  • a valid configuration path resolving the port value.

An implemented API operation can serve as a connection source for incoming requests and as a target for corresponding output behavior, subject to the API contract.


Configuration and context declarations require explicit aliases:

use config AppConfig as cfg
use context RequestContext as ctx

Configuration supplies typed runtime settings to the deployable service. Context supplies supported execution or request-scoped information.

Aliases must be unique within the service.


Broker aliases are required:

use broker OrderBroker as broker

Database aliases are optional:

use database PurchaseOrder as orders
use database Party

Brokers expose typed topics or messaging patterns. Databases expose typed queries, commands, or entities according to their own DSL contracts.


use expression OrderInit
use expression SystemInit as systemInit
use fsm OrderFSM as orderFsm
use component OrderFlow as orderFlow

FSM aliases are required. Expression and component aliases are optional.

Expressions provide stateless logic, FSMs provide stateful behavior, and components provide stateless behavioral composition.


use function HashPassword as hash
use vault MainVault as secrets

Function and vault aliases are optional.

Functions expose supported callable behavior. Vault use makes the vault’s typed secret declarations available to the service according to the vault and generator contracts; secret values remain externally managed.


Explicit aliases are required for:

  • use config;
  • use context;
  • use broker;
  • use fsm.

Aliases are optional for:

  • use api;
  • impl api;
  • use database;
  • use expression;
  • use component;
  • use function;
  • use vault.

All effective local names must be unique. When an alias is declared, service references should use that local identity consistently.


init declares initialization behavior:

init systemInit(config:cfg)
init OrderInit

Initialization entries preserve declaration order.

They must resolve to expressions or other supported callable elements available in the service scope, and supplied arguments must satisfy the target signature.

Initialization occurs as part of service startup according to the target runtime contract.


Connections route typed values or signals between service elements.

connect <source> -> <target>

Example:

connect api.createOrder -> orderFlow.orderRequest

Sources and targets use injected aliases and their exposed operations, ports, topics, commands, queries, inputs, or outputs.


Every connection is type-checked.

Without a mapper, the source output and target input must be compatible under the Ocean type system.

Conceptually:

source output type ── compatible with ── target input type

Unresolved endpoints, invalid direction, incompatible types, or ambiguous aliases are validation errors.


A connection may declare a mapper when source and target types require explicit transformation.

Conceptual form:

connect <source> -<mapper>-> <target>

Example:

connect api.createOrder -MapOrderRequest-> orderFlow.orderRequest

The mapper must resolve to a compatible expression or function. Exact mapper parsing and invocation must follow the common connection grammar implemented by Ocean.


A source may connect to multiple targets where supported:

connect orderFlow.orderCreated -> broker.orderCreated, orders.create

Each target is validated independently. Fan-out does not relax type compatibility or endpoint-direction rules.

Current binding modifiers may restrict a connection line to one bind even when it contains multiple targets.


Supported service flows include:

Source Target Meaning
API input Component or FSM input Route an incoming operation to behavior
Component or FSM output API output Produce an API response
Broker topic Component, FSM, or expression input Consume a message
Component, FSM, or expression output Broker topic Publish a message
Component or FSM output Database command Persist or mutate data
Database query result Component or FSM input Route retrieved data
Component output Component input Chain composed behavior

The referenced element contracts determine the precise valid directions and types.


Broker connections may carry pattern-specific binds such as repetition or timeout where supported.

Conceptual examples:

connect api.method -> broker.topic
connect expression -> broker.topic, each(5s)
connect api.method -> broker.topic, timeout(1s)

Publish targets must use publish-capable topics; subscription sources must use subscribe-capable topics; request-response flows must use compatible request-response topics.

Only one bind per connection line is currently supported.


aggregate declares a service-level aggregation using the common aggregation grammar:

aggregate <aggregation-expression>

Aggregation combines supported results or signals into a service flow. Referenced sources, output type, completion behavior, and aliases must resolve according to the aggregation contract.

Aggregation is distinct from a simple point-to-point connection.


The service section supports imports of:

  • api;
  • broker;
  • expression;
  • fsm;
  • component;
  • config.

Example:

@service
@import api O.std.order.OrderAPI@1.0.0 as OrderAPI
@import fsm O.std.order.OrderFSM@1.1.0 as OrderFSM
@import expression O.std.validation.Validator@2.0.0 as Validator
@import component O.core.AuditTrail@3.0.0 as AuditTrail

The same import form may use P. references for local Pre-baked items where an item of the imported type is available.

Imported definitions are referenced through their declared import aliases.


A service file may include compatible @service definitions through the common @include mechanism.

Included and local services form one logical service section and are validated together. Cross-section inclusion is invalid.

The exact reference, placement, transitivity, and cycle rules are defined by dsl.include.


@service
OrderService
port: rest
use config AppConfig as cfg
use context RequestContext as ctx
impl api OrderAPI as api on rest
use api EmailAPI as email
use broker OrderBroker as broker
use database PurchaseOrder as orders
use expression OrderInit
use expression SystemInit as systemInit
use fsm OrderFSM as orderFsm
use component OrderFlow as orderFlow
use vault MainVault as secrets
init systemInit(config:cfg)
init OrderInit
connect api.createOrder -> orderFlow.orderRequest
connect broker.confirmShipment -> orderFlow.shipmentConfirmed
connect orderFlow.orderCreated -> broker.orderCreated
connect orderFlow.orderCreated -> orders.create
connect orderFlow.emailTriggered -> email.send

A service is deployable, but deployment policy is defined separately.

@service defines what the unit contains and how it behaves. @deploy determines how a service is materialized for an environment or target.

@service → logical deployable unit
@deploy → environment and target materialization

Generators may derive code, configuration, infrastructure integration, and packaging from the combined model.


Validation includes:

  • valid and unique service names;
  • resolution of every used or implemented item;
  • required aliases and alias uniqueness;
  • required port binding for every implemented API;
  • port and configuration-path resolution;
  • API dependency versus fulfillment semantics;
  • initialization target and argument validation;
  • connection endpoint and direction validation;
  • source/target type compatibility;
  • mapper resolution and signature compatibility;
  • broker-pattern compatibility;
  • one-bind-per-connection limitation;
  • aggregation validation;
  • import and include validation;
  • section-specific metadata validation.

Failures must identify the service and offending declaration.


Missing implemented-API port:

impl api PublicAPI as api

Missing required alias:

use config AppConfig

Abbreviated keywords:

use expr Validator
use comp AuditTrail

These are invalid; use use expression and use component.

Type-incompatible connection:

connect api.createOrder -> orderFlow.integerInput

Invalid when the source and target types are incompatible and no valid mapper is supplied.


  • A service file starts with @service.
  • A file may define multiple services.
  • Services are deployable orchestration boundaries.
  • use api declares an API dependency.
  • impl api declares API fulfillment and requires on <port>.
  • Ports may be declared symbols or resolvable configuration paths.
  • Config, context, broker, and FSM uses require aliases.
  • Database, expression, component, function, vault, and API aliases are optional.
  • Effective local names are unique within a service.
  • Initialization order is preserved.
  • Connections use resolvable local endpoints.
  • Connections are directional and typed.
  • Incompatible types require a valid explicit mapper.
  • A source may target multiple endpoints where supported.
  • Only one bind per connection line is currently supported.
  • Broker endpoints must match their declared messaging patterns.
  • Aggregations follow the common aggregation grammar.
  • Supported service imports are API, broker, expression, FSM, component, and config.
  • Imported definitions are referenced through their import aliases.
  • Same-section composition follows dsl.include.
  • Deployment policy belongs to dsl.deploy.

  • concept.control-structure — explains the service’s role in Ocean behavioral composition.
  • dsl.api — defines consumed and implemented API contracts.
  • dsl.broker — defines messaging topics and patterns.
  • dsl.database — defines persistence commands, queries, and entities.
  • dsl.expression — defines stateless logic and mappers.
  • dsl.fsm — defines stateful behavior.
  • dsl.component — defines stateless behavioral composition.
  • dsl.config — defines typed runtime configuration.
  • dsl.context — defines supported contextual data.
  • dsl.vault — defines typed secrets used by services.
  • dsl.import and dsl.include — define reuse mechanisms.
  • dsl.deploy — defines deployment materialization.

These relationships are declared in the metadata.