AWS Lambda Platform (Development) ​
This page is the canonical TPF guide for FUNCTION platform builds that target AWS Lambda. For the broader multi-cloud function story, pair it with the Multi-Cloud Function Providers Guide.
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
FUNCTION does not currently support gRPC transport. If you select FUNCTION, the generated runtime must use REST.
Supported FUNCTION step shapes today:
| Step shape | Status in FUNCTION mode | Notes |
|---|---|---|
UNARY_UNARY | Supported | Canonical handler path in bridge-backed FUNCTION mode. |
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.
Other Function Targets ​
AWS Lambda is the most complete provider-specific development guide in the current docs, but it is not the only FUNCTION target in the repo.
Current repo-supported function targets are:
- AWS Lambda
- Azure Functions
- Google Cloud Run functions
Use these guides for the broader function-platform story:
- Multi-Cloud Function Providers Guide
- Azure Functions Platform
- Google Cloud Run Functions Platform
- Search Azure Functions Testing Guide
Current scope notes:
- The Google function path is best described today as Cloud Run functions; the current repo implementation still uses the Quarkus Google Cloud Functions extension.
- Azure Durable Functions are not a separate TPF platform mode and do not change TPF runtime semantics.
- Queue-backed HA and checkpoint handoff remain part of the
COMPUTE+QUEUE_ASYNCorchestrator path rather than theFUNCTIONpath.
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,InvocationModeRoutingFunctionInvokeAdapterdelegates to the remote adapter; if no concrete adapter is configured,UnsupportedRemoteFunctionInvokeAdapterthrowsUnsupportedOperationExceptionwithFunction invocation mode is REMOTE but no remote invoke adapter is configured, so invocation fails immediately instead of falling back toLOCAL
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 serialisation 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 behaviour 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 behaviour 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 behaviour 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 behaviour, 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.