Ir al contenido
Español

HTTP endpoints

Esta página aún no está disponible en tu idioma.

The management server exposes a small set of operational endpoints. Most are read-only (safe to expose to monitoring); admin ones are opt-in.

Liveness — is this process fundamentally healthy?

GET /health
→ 200 OK
{
"ok": true,
"checks": {
"actor-system-alive": { "ok": true }
}
}

503 with { ok: false } if a check fails. See Health checks.

Readiness — should this pod receive traffic?

GET /ready
→ 200 OK
{
"ok": true,
"checks": {
"actor-system-alive": { "ok": true },
"cluster-up": { "ok": true }
}
}

The cluster-up check fails until SelfUp fires. Custom checks contribute to the response. 503 if any fails.

Available when cluster is passed to HttpManagement.start.

GET /cluster/members
→ 200 OK
{
"selfAddress": "actor-ts://my-app@10.0.0.5:2552",
"leader": "actor-ts://my-app@10.0.0.5:2552",
"members": [
{
"address": "actor-ts://my-app@10.0.0.5:2552",
"status": "up",
"roles": ["compute"],
"uniqueAddress": { "address": "...", "uid": 1 }
},
...
]
}

Full membership snapshot. Useful for:

  • Manual cluster-state checks during incidents.
  • External dashboards that visualize the cluster.
  • Tests verifying cluster joining.
GET /cluster/leader
→ 200 OK
{ "leader": "actor-ts://my-app@10.0.0.5:2552" }

Just the leader’s address. Useful for monitoring leadership churn.

GET /cluster/shards?type=cart
→ 200 OK
{
"typeName": "cart",
"regions": [
{
"address": "actor-ts://my-app@10.0.0.5:2552",
"shards": [0, 1, 2, ..., 33]
},
{
"address": "actor-ts://my-app@10.0.0.6:2552",
"shards": [34, 35, ..., 66]
},
...
]
}

Shows the shard-to-region allocation for a sharded type. Use for:

  • Verifying even distribution after a rebalance.
  • Diagnosing hot regions (one region with too many shards).
  • Manual rebalance triggers in development.

Opt-in via enableMetricsEndpoint: true.

GET /metrics
→ 200 OK
Content-Type: text/plain; version=0.0.4
# HELP actor_messages_processed_total ...
# TYPE actor_messages_processed_total counter
actor_messages_processed_total{class="Worker",path="..."} 12345
...

Prometheus text format. See Prometheus exporter.

Opt-in via enableLeaveEndpoint: true.

POST /cluster/leave
→ 200 OK
{ "status": "leaving" }

Triggers graceful cluster-leave. The node transitions through leavingexitingremoved; shards rebalance away; the actor system terminates (configurable).

Use for:

  • Pod retirement before rolling-update.
  • Manual node-out during incidents.

Gate behind authentication — anyone with port access can drain your node.

Opt-in via enableDownEndpoint: true.

POST /cluster/down
{ "address": "actor-ts://my-app@10.0.0.5:2552" }
→ 200 OK
{ "downed": "actor-ts://my-app@10.0.0.5:2552" }

Force-downs a remote member by address. Destructive — the target’s actors stop, its shards reallocate elsewhere.

Use for:

  • Split-brain recovery when no downing strategy is configured.
  • Removing stuck unreachable members that refuse to recover.

High-risk endpoint — gate behind auth + audit logs.

import { managementRoutes, path, get, concat, completeJson } from 'actor-ts';
const baseRoutes = managementRoutes(system, cluster).routes;
const customRoutes = concat(
baseRoutes,
path('admin',
get(async () => completeJson(200, { appVersion: '1.2.3' })),
),
);
await http.newServerAt(host, port).bind(customRoutes);

managementRoutes(system, cluster, opts) returns the base routes; combine with your own using concat. Useful for adding app-specific admin endpoints alongside the standard set.

All endpoints return JSON by default, with one exception: /metrics returns text/plain for Prometheus.

Errors are structured:

{
"error": "Missing query parameter: type",
"status": 400
}

Status codes follow HTTP conventions: 200 for success, 4xx for client errors, 5xx for server errors.

The privileged endpoints (/cluster/down, /cluster/leave, /cluster/members, /cluster/shards, /metrics) accept anonymous requests by default. That’s only safe when the management port is on a network-isolated bind (a separate Service, a different port, 127.0.0.1-only) or behind a reverse-proxy that does authentication for you.

For production deployments that expose management endpoints to a broader network, attach the built-in middlewares via managementRoutes(system, cluster, { auth, ipAllowlist }):

import {
BearerTokenAuth,
IpAllowlist,
managementRoutes,
} from 'actor-ts';
const { routes } = managementRoutes(system, cluster, {
enableLeaveEndpoint: true,
enableDownEndpoint: true,
enableMetricsEndpoint: true,
// Shared-secret bearer token (rotation supported via multiple entries).
auth: BearerTokenAuth({
tokens: [process.env.MGMT_TOKEN!],
realm: 'my-app-mgmt',
}),
// Network-level fence — only requests from these CIDRs reach
// the application at all.
ipAllowlist: IpAllowlist({
allow: ['10.0.0.0/8', '127.0.0.1/32'],
// Operators behind a trusted reverse-proxy: pass a custom
// extractor that reads x-forwarded-for (the default reads
// the socket peer and ignores forwarded headers).
// getClientIp: (req) => req.headers['x-forwarded-for']?.split(',')[0]?.trim(),
}),
});

Policy split:

  • auth wraps the privileged subset (/cluster/*, /metrics). /health and /ready stay anonymous — Kubernetes liveness/readiness probes can’t easily attach an Authorization header. Set authProtectHealth: true when your deployment guarantees the probes can present credentials.
  • ipAllowlist wraps EVERY endpoint including /health and /ready. Network-level isolation is independent of who’s authenticated.

Failure modes:

  • Missing / wrong Authorization header → 401 Unauthorized with WWW-Authenticate: Bearer realm="...".
  • Client IP outside the allowlist (or unresolvable) → 403 Forbidden.

The middlewares are general-purpose — you can use them outside the management subtree via the withMiddleware(mw, route) builder.