Annotations ​
The Pipeline Framework uses @PipelineStep to mark internal execution services that are referenced from YAML.
@PipelineStep ​
@PipelineStep is the discovery marker for internal service: steps. It does not define the step contract by itself. Current internal-step contract metadata belongs in pipeline.yaml.
For internal services, YAML is the canonical source of truth for:
servicecardinalityinputoutputinboundMapperoutboundMapper
Current Usage ​
steps:
- name: process-payment
service: com.app.payment.ProcessPaymentService
cardinality: ONE_TO_ONE
input: com.app.domain.PaymentRecord
output: com.app.domain.PaymentStatus
inboundMapper: com.app.payment.PaymentRecordMapper
outboundMapper: com.app.payment.PaymentStatusMapper@PipelineStep(
ordering = OrderingRequirement.RELAXED,
threadSafety = ThreadSafety.SAFE
)
@ApplicationScoped
public class ProcessPaymentService implements ReactiveService<PaymentRecord, PaymentStatus> {
@Override
public Uni<PaymentStatus> process(PaymentRecord input) {
// Implementation
}
}Keep on the Annotation ​
Use @PipelineStep for Java-local execution concerns:
cacheKeyGeneratororderingthreadSafetyrunOnVirtualThreadssideEffectdelegate(for operator steps only)
Compatibility-Only Members ​
The following @PipelineStep members remain supported for legacy internal services, but are deprecated for current authoring:
inputTypeoutputTypeinboundMapperoutboundMapperstepTypebackendType
New internal services should not author those members.
Operator-Specific YAML Fields (Legacy) ​
For operator/delegated steps, the following fields were previously supported on the @PipelineStep annotation but are now configured exclusively in YAML:
operator(use aclass::methodreference, e.g.,operator: com.example.OperatorClass::method)operatorMapperexternalMapper
These operator-specific fields must use fully-qualified class::method references in YAML and are resolved/validated at build time. They are not part of the current @PipelineStep authoring surface for internal services.
Usage ​
- Define the internal step contract in
pipeline.yaml. - Annotate the implementation class with
@PipelineStep. - Implement the matching reactive service interface:
ReactiveService<I, O>ReactiveStreamingService<I, O>ReactiveStreamingClientService<I, O>ReactiveBidirectionalStreamingService<I, O>- or the matching blocking interface when the step is intentionally synchronous:
BlockingService<I, O>BlockingStreamingService<I, O>BlockingIteratorService<I, O>BlockingStreamingClientService<I, O>BlockingBidirectionalStreamingService<I, O>
- Keep YAML cardinality aligned with the implemented interface, reactive or blocking.
Parallelism is configured at the pipeline level (pipeline.parallelism and pipeline.max-concurrency). The ordering and threadSafety values on @PipelineStep are propagated to the generated client step, which the runtime uses to decide parallelism under AUTO.
Blocking services are offloaded by default onto worker threads so the framework does not execute them on event-loop threads. Set runOnVirtualThreads = true when you want the generated blocking bridge and server entrypoints to use virtual threads instead of the default worker pool.
Transport selection (gRPC vs REST) is configured in pipeline.yaml, not on the annotation.
Blocking vs Reactive ​
Use the blocking path when the business code is naturally synchronous and the team is not going to maintain Mutiny-based implementations.
- The framework still generates reactive transport adapters.
- Internal blocking services are wrapped in a generated reactive bridge.
BlockingStreamingService,BlockingStreamingClientService, andBlockingBidirectionalStreamingServiceuse materializedListsemantics.BlockingIteratorServicekeepsONE_TO_MANYincremental without forcing Mutiny into user method signatures.
Decision guide:
| Need | Contract |
|---|---|
| Bounded batch, blocking SDKs, or simple synchronous code | Materializing blocking interfaces |
| Incremental blocking streaming from an iterator/reader/cursor API | BlockingIteratorService |
| End-to-end backpressure, async I/O, or highest streaming throughput | Reactive interfaces |