Skip to main content

hello + formatter

hello demonstrates the SDK author API; formatter is an independently built service with its own payload types. Neither service imports the other. The installation connects them through the public console API:

GET /hello/?name=ann
-> hello.Greet hook -> binding -> formatter.Format
-> response "Welcome, ann!"
-> hello.Greeted {name, count, text}
-> hello audit reactor
-> formatter reactor (its own copy of the event schema)
-> rule -> formatter.Record

Run locally​

From the repository root, start the infrastructure with make up. Then run these commands in separate terminals:

make run-backplane
make run-hello
make run-formatter

All three use local Consul, NATS and Temporal. Public ports are backplane 8090, hello 8080, formatter 8082, hello legacy 8083; console 8081; platform ports 9410, 9400, 9420. The legacy port is declared in the versioned manifest and must stay stable across restarts (HELLO_LEGACY_LISTEN). Once both services appear healthy in the catalog:

make setup-example
curl 'http://localhost:8080/hello/?name=ann'
curl 'http://localhost:8082/formatter/'

Setup logs in with BACKPLANE_ADMIN_TOKEN (default DEV_ADMIN_TOKEN from Makefile), opens the cookie-authenticated /ws and saves the binding and rule. It reuses the named rule on repeated execution; definitions receive new versions. BACKPLANE_DEMO_URL overrides the default http://localhost:8081, including a console prefix if one is configured. The setup source and DSL live in examples/demo; the same setup runs in conformance.

Without a binding, hello renders locally. Without infrastructure, its local fallback still works. Bound HTTP greetings and bound Welcome workflow calls record the returned text and emit Greeted, just like local greetings. The rule excludes the name skip; the independent reactor still observes it. Publication failure is logged and does not fail the greeting. Idempotency-Key deduplicates the hook execution, not HTTP requests or their greeting events.

SDK features and where to see them​

CapabilityExample
Required/optional dependencies, probes, retry, shutdownhello internal/store, cmd/hello
Lifecycle, goroutines, singleton, telemetryhello internal/greeter
Live config, validation, watchgreeter.suffix, greeter.excited; formatter.prefix, formatter.suffix
Native gRPC, streaming, ws-protohello HelloService, Countdown
HTTP, GraphQL, route policies, separate listenerhello internal/web, internal/legacy
Internal console API and plugin bundle deliveryhello internal/admin, ui
Hook Call / workflows.CallHook, idempotency keyhello Greet, HTTP handler / Welcome
Activity, workflow-backed activity, execution metadatahello Echo, Welcome; formatter Format, Record
Workflows available for administrative runs and scheduleshello GreetMany, Report; SDK creates no schedules
Events, reactors, delivery metadata, deduplicationhello Greeted, audit; formatter independent reactor
Cross-service CEL binding and event ruleexamples/demo
Invalid event / DLQ / redrivepublish hello.Greeted with an empty name: both reactors reject it terminally; console EventService exposes DLQ and targeted redrive

Formatter's public /formatter/ endpoint reports formatted, recorded, observed and last_text. Its example counters and deduplication window (4096 keys) are process-local; persistent business data belongs in a real store. The UI bundle runs in the console Module Federation host with the shared client, router, theme and translations. Authors can run the same pages independently; see module template.

Verification​

make test
make conformance
make test-m1
make test-m2
make test-replicas

Run live targets sequentially with no manually running example processes. M1/M2/replicas use real binaries built with the race detector. test-replicas starts two backplanes against one scratch database, plus hello and formatter. It checks shared rule consumers, one workflow per event even after duplicate publication, configuration reconciliation, bound greeting events, both reactor and rule delivery, crash and rejoin of one backplane, and endpoint retirement with retained manifests followed by service return. Test-owned processes, streams, Consul keys, endpoint and database are cleaned up.

Hello UI delivery​

Hello declares its console module only when HELLO_UI_ASSETS points to a real built bundle. make dev builds web/templates/module/dist/plugin and mounts it into hello. Running the Go example alone without that variable serves its APIs without advertising a nonexistent UI. To attach the module to a host process:

cd web
yarn build:packages
yarn workspace @backplane/module-template build
cd ..
HELLO_UI_ASSETS="$PWD/web/templates/module/dist/plugin" make run-hello

Authors who ship assets inside their own binary can pass an embedded filesystem to svc.UI; see the module delivery contract. The reference example uses the deployment-owned directory so Go tests and builds do not require Node or generated JavaScript assets.