Service DSL Reference
1. Overview
Section titled “1. Overview”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.
2. Core Principle
Section titled “2. Core Principle”A service owns orchestration and deployment-facing integration—not the internal state of domain behavior.
APIs ─────────┐Brokers ──────┤Databases ────┤Config ───────┼── Service ── Components / FSMs / ExpressionsContext ──────┤Vaults ───────┤Functions ────┘Components own composition, FSMs own behavioral state, and expressions own stateless logic. The service connects these capabilities into a deployable boundary.
3. Syntax Overview
Section titled “3. Syntax Overview”@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.
4. Service Names
Section titled “4. Service Names”Service names follow the Ocean type-name convention and must be unique within the resolved service scope.
Examples:
OrderServiceInventoryServicePaymentOrchestratorA service name identifies the deployable model unit; target-specific deployment names may be derived separately.
5. Ports
Section titled “5. Ports”Ports are declared as a comma-separated list:
port: rest, adminPorts provide symbolic binding points for implemented APIs.
An implemented API selects a port using on:
impl api PublicAPI as publicApi on restA port may also be resolved from configuration:
impl api AdminAPI as adminApi on cfg.ports.adminPortPort symbols and configuration paths must resolve unambiguously.
6. Use and Implementation Declarations
Section titled “6. Use and Implementation Declarations”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 APIimpl api → service exposes and fulfills an APIAliases provide the local identity used in connections and calls.
7. API Dependencies
Section titled “7. API Dependencies”use api PartnerAPIor:
use api PartnerAPI as partnerA 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.
8. API Implementations
Section titled “8. API Implementations”impl api OrderAPI as api on restimpl 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.
9. Config and Context
Section titled “9. Config and Context”Configuration and context declarations require explicit aliases:
use config AppConfig as cfguse context RequestContext as ctxConfiguration supplies typed runtime settings to the deployable service. Context supplies supported execution or request-scoped information.
Aliases must be unique within the service.
10. Brokers and Databases
Section titled “10. Brokers and Databases”Broker aliases are required:
use broker OrderBroker as brokerDatabase aliases are optional:
use database PurchaseOrder as ordersuse database PartyBrokers expose typed topics or messaging patterns. Databases expose typed queries, commands, or entities according to their own DSL contracts.
11. Expressions, FSMs, and Components
Section titled “11. Expressions, FSMs, and Components”use expression OrderInituse expression SystemInit as systemInituse fsm OrderFSM as orderFsmuse component OrderFlow as orderFlowFSM aliases are required. Expression and component aliases are optional.
Expressions provide stateless logic, FSMs provide stateful behavior, and components provide stateless behavioral composition.
12. Functions and Vaults
Section titled “12. Functions and Vaults”use function HashPassword as hashuse vault MainVault as secretsFunction 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.
13. Alias Rules
Section titled “13. Alias Rules”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.
14. Initialization
Section titled “14. Initialization”init declares initialization behavior:
init systemInit(config:cfg)init OrderInitInitialization 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.
15. Connections
Section titled “15. Connections”Connections route typed values or signals between service elements.
connect <source> -> <target>Example:
connect api.createOrder -> orderFlow.orderRequestSources and targets use injected aliases and their exposed operations, ports, topics, commands, queries, inputs, or outputs.
16. Connection Compatibility
Section titled “16. Connection Compatibility”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 typeUnresolved endpoints, invalid direction, incompatible types, or ambiguous aliases are validation errors.
17. Mappers
Section titled “17. Mappers”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.orderRequestThe mapper must resolve to a compatible expression or function. Exact mapper parsing and invocation must follow the common connection grammar implemented by Ocean.
18. Fan-out
Section titled “18. Fan-out”A source may connect to multiple targets where supported:
connect orderFlow.orderCreated -> broker.orderCreated, orders.createEach 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.
19. Common Connection Directions
Section titled “19. Common Connection Directions”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.
20. Broker Patterns and Binds
Section titled “20. Broker Patterns and Binds”Broker connections may carry pattern-specific binds such as repetition or timeout where supported.
Conceptual examples:
connect api.method -> broker.topicconnect 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.
21. Aggregation
Section titled “21. Aggregation”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.
22. Imports
Section titled “22. Imports”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 AuditTrailThe 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.
23. Includes
Section titled “23. Includes”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.
24. Complete Example
Section titled “24. Complete Example”@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.send25. Deployment Boundary
Section titled “25. Deployment Boundary”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 materializationGenerators may derive code, configuration, infrastructure integration, and packaging from the combined model.
26. Validation
Section titled “26. Validation”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.
27. Invalid Examples
Section titled “27. Invalid Examples”Missing implemented-API port:
impl api PublicAPI as apiMissing required alias:
use config AppConfigAbbreviated keywords:
use expr Validatoruse comp AuditTrailThese are invalid; use use expression and use component.
Type-incompatible connection:
connect api.createOrder -> orderFlow.integerInputInvalid when the source and target types are incompatible and no valid mapper is supplied.
28. Rules and Constraints
Section titled “28. Rules and Constraints”- A service file starts with
@service. - A file may define multiple services.
- Services are deployable orchestration boundaries.
use apideclares an API dependency.impl apideclares API fulfillment and requireson <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.
29. Related Knowledge
Section titled “29. Related Knowledge”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.importanddsl.include— define reuse mechanisms.dsl.deploy— defines deployment materialization.
These relationships are declared in the metadata.