Install
$ agentstack add skill-resonatehq-resonate-skills-resonate-http-service-design-typescript ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Resonate HTTP Service Design
> SDK version: This skill reflects @resonatehq/sdk v0.10.0 (current on npm).
Overview
Use this skill to design HTTP services where route handlers start or await durable workflows. The HTTP server is the entrypoint; durable functions do the work and coordinate via Resonate. Downstream services (like a database service) expose their own durable functions and are invoked via RPC.
Architecture Model
- HTTP service: Express/Fastify server handling routes and mapping requests to durable workflows.
- Worker service: Resonate worker group that runs durable functions for business logic.
- DB service: Separate worker group exposing durable DB functions via Resonate RPC.
- Resonate Server: Durable promise store and coordination hub.
client -> HTTP routes -> Resonate Client (beginRpc/run)
-> worker group (durable workflow)
-> ctx.rpc -> db worker group (durable db functions)
Rules
- Route handlers are ephemeral: use Resonate Client APIs, not Context APIs.
- Durable functions are generator functions:
function*withyield*. - All external effects occur in durable steps and are awaited or explicitly detached.
- Use stable promise IDs for idempotency and replay safety.
Route Design Patterns
1) Submit and poll (async HTTP)
POST /jobsstarts a workflow and returnsjobId.GET /jobs/:idreturns status or result.
2) Submit and callback
POST /jobsstarts a workflow and returnsjobId.- External system resolves a promise when done.
3) Webhook gate
POST /webhooks/serviceresolves a durable promise tied to a workflow.
Code Examples
HTTP server entrypoints (Express)
import express from "express";
import { Resonate } from "@resonatehq/sdk";
import crypto from "node:crypto";
const app = express();
app.use(express.json());
const resonate = new Resonate({
url: "http://localhost:8001",
group: "api",
});
// Start workflow
app.post("/jobs", async (req, res) => {
const jobId = `job/${crypto.randomUUID()}`;
await resonate.beginRpc(
jobId,
"process-job",
req.body,
resonate.options({ target: "poll://any@workers" })
);
res.status(202).json({ id: jobId });
});
// Poll status
app.get("/jobs/:id", async (req, res) => {
const handle = await resonate.get(req.params.id);
const result = await handle.result();
res.json({ id: req.params.id, result });
});
// Webhook: external system resolves promise
app.post("/webhooks/approval", async (req, res) => {
const { promiseId, approved } = req.body;
await resonate.promises.settle(promiseId, "resolved", {
data: JSON.stringify({ approved }),
});
res.status(204).end();
});
Worker service (durable workflow)
import { Resonate, type Context } from "@resonatehq/sdk";
const resonate = new Resonate({ url: "http://localhost:8001", group: "workers" });
function* processJob(ctx: Context, payload: { accountId: string }) {
const account = yield* ctx.rpc(
"db.getAccount",
payload.accountId,
ctx.options({ target: "poll://any@db" })
);
const result = yield* ctx.run(processAccount, account);
const approval = yield* ctx.promise({ id: `approve/${ctx.id}` });
const ok = yield* approval as boolean;
if (!ok) {
throw new Error("rejected");
}
yield* ctx.rpc(
"db.saveResult",
{ id: ctx.id, result },
ctx.options({ target: "poll://any@db" })
);
return { status: "done", result };
}
resonate.register("process-job", processJob);
DB service (durable database functions)
import { Resonate, type Context } from "@resonatehq/sdk";
const resonate = new Resonate({ url: "http://localhost:8001", group: "db" });
function* getAccount(_: Context, id: string) {
return await db.loadAccount(id);
}
function* saveResult(_: Context, record: { id: string; result: unknown }) {
await db.save(record);
return { ok: true };
}
resonate.register("db.getAccount", getAccount);
resonate.register("db.saveResult", saveResult);
Determinism Notes
- Use
ctx.date.now()andctx.math.random()inside durable functions. - Wrap side effects in durable steps (
ctx.run,ctx.rpc). - Ensure returned objects are serializable.
Structured Concurrency Example
function* aggregate(ctx: Context, ids: string[]) {
const futures = ids.map((id) =>
ctx.beginRpc("db.getAccount", id, ctx.options({ target: "poll://any@db" }))
);
const results = [];
for (const f of futures) {
results.push(yield* f);
}
return results;
}
Error Handling
- Throw errors for normal failures; Resonate retries by default.
- Use
ctx.options({ timeout: ... })to bound retries. - Treat 40900 (promise exists) as idempotency, not failure.
Promise ID Strategy
- Use request-derived IDs for idempotency, or generate UUIDs for fire-and-forget.
- Keep IDs readable:
job/,approve/,db/op/.
Route Checklist
- Inputs validated and serialized before RPC.
- Durable workflow entrypoint registered and reachable.
- Target group matches worker group name.
- Promise ID uniqueness guaranteed.
- Routes return 202 + ID for async workflows.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: resonatehq
- Source: resonatehq/resonate-skills
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.