Documentation / Build

Connect your handlers

Any executable can be a handler. Read one JSON context from stdin and write one JSON outcome to stdout.

Map a service to a command

json
{
  "version": 1,
  "handlers": {
    "hello": {
      "command": [
        "python3",
        "handler.py"
      ],
      "timeoutSeconds": 30
    }
  }
}

Paths are relative to the manifest directory. Commands are argument arrays, not shell strings.

Implement the contract

Python

python
import json
import sys

context = json.load(sys.stdin)
print(json.dumps({"outcome": "completed", "payload": context.get("options")}))

Node.js

node
import { readFileSync } from "node:fs";
const context = JSON.parse(readFileSync(0, "utf8"));
console.log(JSON.stringify({
  outcome: "completed",
  payload: context.options ?? null
}));

Rust

rust
use rippflow_sdk::{run_handler, PhaseOutcome};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    run_handler(|context| {
        Ok(PhaseOutcome::completed().with_payload(context.options))
    })
}

Java

java
import com.google.gson.*;
import java.io.InputStreamReader;

public class Handler {
  public static void main(String[] args) {
    JsonObject context = JsonParser.parseReader(
      new InputStreamReader(System.in)).getAsJsonObject();
    JsonObject result = new JsonObject();
    result.addProperty("outcome", "completed");
    result.add("payload", context.get("options"));
    System.out.println(new Gson().toJson(result));
  }
}

Package a handler for Lambda

The runner uses an OS-only Lambda runtime. Build for the function’s Linux architecture. Lambda layers unpack into /opt. For Python, Node.js or Java, include the interpreter or JVM and your dependencies in the layer or container image.

LanguageExample handler command
Rust/opt/bin/workflow-handler
Python/opt/bin/python3 /opt/handlers/handler.py
Node.js/opt/bin/node /opt/handlers/handler.mjs
Java/opt/java/bin/java -jar /opt/handlers/handler.jar

The adapter starts a JVM per Java invocation. Handler processes share the runner’s memory and timeout and, by default, its IAM permissions. See Identity & isolation for scoped credentials.

Keep the boundary simple

  • Return a declared outcome; use stderr for logs.
  • Exit nonzero for a handler error.
  • Use the generated Rust SDK or Java/Gson template for their build setup.

Handlers are trusted programs with your machine's access. A Docker wrapper is not a security sandbox.

Verified sources

Checked 2026-11-05.

Let's talk

Contact Rippflow

Tell us about your workflows, deployment or pricing.

We'll reply to your email.

Search docs

Search workflows, handlers and operations.