AWS Lambda Platform (Development)
This page is the canonical TPF guide for building pipeline applications for AWS Lambda.
What TPF Supports Today
- Platform mode:
FUNCTION(default platform remainsCOMPUTE) - Transport mode:
REST(required in Function mode) - Step shapes: unary and streaming shapes are supported in FUNCTION mode through generated adapter/bridge wiring
Supported FUNCTION step shapes today:
| Step shape | Status in FUNCTION mode | Notes |
|---|---|---|
UNARY_UNARY | Supported | Canonical handler path in B. |
UNARY_STREAMING | Supported | Adapter/bridge generated (invokeOneToMany). |
STREAMING_UNARY | Supported | Adapter/bridge generated (invokeManyToOne). |
STREAMING_STREAMING | Supported | Adapter/bridge generated (invokeManyToMany). |
Set platform mode during build:
./mvnw -f <app-parent>/pom.xml \
-Dtpf.build.platform=FUNCTION \
-Dtpf.build.transport=REST \
-Dtpf.build.lambda.scope=compile \
-Dquarkus.profile=lambda \
clean verifyTPF uses build switches for this mode. It does not require a dedicated Maven profile.
Checkpoint Handoff Is Not Available In FUNCTION Mode
Checkpoint publication and subscription are not available in FUNCTION mode.
If your application depends on reliable cross-pipeline handoff, use COMPUTE + QUEUE_ASYNC orchestrators instead. This is a platform-selection constraint for multi-pipeline applications requiring reliable checkpoint handoff, such as multi-pipeline checkout topologies.
Required and Optional Quarkus Extensions
Required for FUNCTION runtime wiring and generated handlers:
io.quarkus:quarkus-amazon-lambda
Optional API Gateway REST bridge (v1 events):
io.quarkus:quarkus-amazon-lambda-restio.quarkus:quarkus-amazon-lambda-rest-event-server(test/dev mock server for REST gateway events)
API Gateway HTTP bridge extensions are outside the canonical TPF FUNCTION path.
Generated Lambda Handlers
In FUNCTION mode, TPF generates native Lambda handlers for REST bindings across supported cardinalities:
- Step handlers implement
RequestHandler<I, O> - Orchestrator handler implements
RequestHandler<I, O> - Handlers delegate to generated TPF resources, preserving pipeline behavior
When multiple handlers exist in one module, choose one explicitly:
quarkus.lambda.handler=PipelineRunFunctionHandlerTPF-generated handlers are annotated with @Named("<HandlerClassName>").
Function Transport Contracts (Preview)
TPF now defines function-transport runtime contracts for native Lambda/event-driven wiring:
org.pipelineframework.transport.function.FunctionSourceAdapterorg.pipelineframework.transport.function.FunctionInvokeAdapterorg.pipelineframework.transport.function.FunctionSinkAdapterorg.pipelineframework.transport.function.TraceEnvelope
These abstractions separate:
- Event ingress → reactive stream (
SourceAdapter) - Orchestrator-to-step invocation across function boundaries (
InvokeAdapter) - Reactive output → egress target (
SinkAdapter)
TraceEnvelope carries lineage, payload model/version, and idempotency metadata without forcing application DTOs to become envelope types.
Invocation Contract Baseline (Milestone C Slice 1)
FunctionTransportContext now defines explicit invocation contract metadata for cross-runtime paths:
tpf.function.invocation.mode=LOCAL|REMOTE(defaults toLOCAL)tpf.function.target.runtime=<runtime-name>(optional)tpf.function.target.module=<module-name>(optional)tpf.function.target.handler=<handler-name>(optional)
Current baseline behavior:
- intra-runtime generated handler paths execute with
LOCALinvocation semantics - runtime mapping still controls placement/topology; invocation metadata provides a stable contract for future/optional remote adapters
- when
REMOTEis set but no remote adapter is configured, handler wiring should still be treated as local unless an app/runtime-specific adapter overrides it
Protobuf-over-HTTP (Unary v1) in FUNCTION Remote Paths
For remote function invocation, you can opt into unary Protobuf-over-HTTP. This protocol variant requires remote mode and keeps REST as the underlying transport:
pipeline.transport=REST
tpf.function.invocation.mode=REMOTE
tpf.transport.protocol=PROTOBUF_HTTP_V1PROTOBUF_HTTP_V1 only takes effect when tpf.function.invocation.mode=REMOTE. It configures payload/error encoding (application/x-protobuf + google.rpc.Status) while REST remains the wire transport.
Choose PROTOBUF_HTTP_V1 when you need smaller binary payloads, existing protobuf schema reuse, or tighter runtime serialization costs. Trade-offs are reduced ad-hoc readability and stricter schema/tooling compatibility requirements compared with JSON.
When enabled:
- request/response media type is
application/x-protobuf - failure envelope is
google.rpc.Status - canonical dispatch metadata is propagated via headers:
x-tpf-correlation-idx-tpf-execution-idx-tpf-idempotency-keyx-tpf-retry-attemptx-tpf-deadline-epoch-msx-tpf-dispatch-ts-epoch-msx-tpf-parent-item-id(optional)
Behavior rules:
- correlation id is immutable after ingress
- deadline is absolute epoch milliseconds
- JSON remote behavior remains default unless this protocol is explicitly enabled
Successful response contract:
- success payload must follow the current adapter decoder contract: protobuf
google.protobuf.BytesValuewhosevaluebytes contain UTF-8 JSON for the envelope payload. - malformed/missing canonical headers should be rejected with deterministic
4xxresponses and failure envelopes; non-conforming protobuf payloads should also fail deterministically (4xxfor validation/contract errors,5xxfor unexpected server failures). - validate and sanitize incoming header values (including numeric fields), and keep TLS plus gateway/signature validation in place to reduce header injection/tampering risk.
ID Ownership and Idempotency Boundaries
TPF distinguishes between business IDs and transport IDs:
- Business IDs (for example CSV row IDs, domain entity IDs) are application-owned.
- Transport IDs (
traceId,itemId, transportidempotencyKey) are framework-owned and opaque to business logic.
TPF does not impose business semantics on transport IDs. Authoritative dedupe/rejection remains in application and data layers (for example domain rules, warehouse checks, JPA/SQL primary keys and unique constraints).
Function Transport Idempotency Policy
Function transport adapters support policy-driven idempotency derivation through FunctionTransportContext attributes:
tpf.idempotency.policy=CONTEXT_STABLE|EXPLICIT(legacyRANDOMaccepted as alias)tpf.idempotency.key=<caller-stable-key>
Behavior:
CONTEXT_STABLE(default): adapter-generated deterministic transport keys from stable context/envelope identifiers (non-authoritative dedupe behavior). These keys provide transport-level correlation and can reduce duplicate processing attempts, but they do not guarantee business/data uniqueness and do not replace explicit business idempotency rules.EXPLICIT: uses caller-provided key where supported; this is the recommended mode when the application already has stable business identifiers. If the key is missing (or an adapter/runtime path does not support explicit override), adapters log a warning and fall back toCONTEXT_STABLEderivation.RANDOM: legacy compatibility alias mapped toCONTEXT_STABLE.
EXPLICIT is an opt-in transport assist, not a replacement for business/data-level uniqueness enforcement.
Shape-To-Bridge Mapping And Failure Semantics
FUNCTION generation supports unary and streaming step cardinalities through bridge/adapters.
| Pipeline shape | Function bridge mapping | Failure semantics |
|---|---|---|
UNARY_UNARY | Generated Lambda handler delegates to generated REST resource for step/orchestrator. | Step/resource failure becomes handler failure for that invocation. Retry/timeout behavior is controlled by Lambda invoke source and TPF retry configuration inside the runtime. |
UNARY_STREAMING | Generated handler delegates through FunctionTransportBridge.invokeOneToMany. | Adapter/bridge path returns list sink output and preserves transport metadata/idempotency policy. |
STREAMING_UNARY | Generated handler delegates through FunctionTransportBridge.invokeManyToOne. | Adapter/bridge path reduces stream input to unary output with bounded collection policy. |
STREAMING_STREAMING | Generated handler delegates through FunctionTransportBridge.invokeManyToMany. | Adapter/bridge path processes streaming input/output with bounded ingress/sink behavior. |
Failure semantics summary:
- Validation failures in FUNCTION mode are now primarily transport-mode related (
pipeline.transport=RESTrequired), while supported streaming shapes generate adapter/bridge wiring. - Invocation failures in unary handlers fail the current function call.
- Retries are not implicit in the bridge itself; they follow configured TPF retry behavior and upstream Lambda/event-source policies.
Backpressure Model in Function Deployments
Backpressure remains active inside each runtime via Mutiny Multi/Uni, but Lambda invocation boundaries are explicit adaptation points:
- inside a runtime: normal reactive demand and overflow handling
- across runtime boundaries: flow control is managed by adapter batching policies and Lambda/event-source concurrency
Operator Notes: Bounded Waits, Timeouts, And Adapter Behavior
Operators should configure bounded waits and clear timeout ownership at function boundaries.
- Lambda timeout should be finite and aligned to worst-case step latency plus retry budget.
- Startup/dependency waits should stay bounded (
pipeline.health.startup-timeout). - Function adapters are boundary adapters, not infinite buffers. Retry/backoff should stay bounded (
pipeline.defaults.retry-limit,pipeline.defaults.retry-wait-ms,pipeline.defaults.max-backoff). - Backpressure behavior inside a runtime remains controlled by step/runtime overflow strategy and capacity settings.
- Adapters preserve reactive semantics inside a runtime; cross-runtime pacing is bounded by Lambda concurrency, event source behavior, and configured batching/overflow policy.
Quarkus Integrations You Can Leverage in TPF Apps
With Quarkus Lambda integrations, app developers can leverage:
- AWS request context injection (request/event/context objects)
- request context attributes via Quarkus REST context (when REST gateway extensions are enabled)
- Security integration and custom identity provider hooks
- Custom Lambda auth mechanism hooks
These are application-level integrations layered on top of generated TPF resources.
X-Ray Extension
For AWS X-Ray integration, use:
io.quarkus:quarkus-amazon-lambda-xray
This is particularly relevant for Lambda deployments, including native-image scenarios where Quarkus supplies required substitutions/runtime support.