HTTP endpoints
此内容尚不支持你的语言。
The management server exposes a small set of operational
endpoints. Most are read-only; the admin ones (/cluster/down,
/cluster/leave) are opt-in and off by default.
Security (security audit #8): the read-only endpoints still reveal
internal topology — member addresses (host:port), roles, the leader, and the
shard map. Treat the management server as sensitive: bind it to an internal
interface and gate it with the ipAllowlist (and/or auth) options of
managementRoutes(...) rather than exposing it publicly.
Health probes
Section titled “Health probes”GET /health
Section titled “GET /health”Liveness — is this process fundamentally healthy?
GET /health→ 200 OK{ "status": "UP", "checks": [ { "name": "event-loop", "status": true } ]}503 with { "status": "DOWN", ... } if any liveness check fails.
See Health checks.
GET /ready
Section titled “GET /ready”Readiness — should this pod receive traffic?
GET /ready→ 200 OK{ "status": "UP", "clusterReady": true, "checks": [ { "name": "database", "status": true } ]}clusterReady is false until the local node reaches Up; the
readiness checks you register contribute the checks array. 503
if the cluster isn’t ready or any check fails.
Cluster info
Section titled “Cluster info”Available when a cluster is passed to managementRoutes.
GET /cluster/members
Section titled “GET /cluster/members”GET /cluster/members→ 200 OK{ "members": [ { "address": "actor-ts://my-app@10.0.0.5:2552", "status": "up", "version": 3, "roles": ["compute"] }, ... ], "self": "actor-ts://my-app@10.0.0.5:2552"}Full membership snapshot. Useful for:
- Manual cluster-state checks during incidents.
- External dashboards that visualize the cluster.
- Tests verifying cluster joining.
GET /cluster/leader
Section titled “GET /cluster/leader”GET /cluster/leader→ 200 OK{ "leader": "actor-ts://my-app@10.0.0.5:2552", "isSelf": true }The leader’s address plus isSelf (is the local node the leader).
leader is null before a leader is elected. Useful for monitoring
leadership churn.
GET /cluster/shards?type=<typeName>
Section titled “GET /cluster/shards?type=<typeName>”GET /cluster/shards?type=cart→ 200 OK{ "typeName": "cart", "leader": "my-app@10.0.0.5:2552", "takenAt": 1710000000000, "regions": [ { "key": "my-app@10.0.0.5:2552", "address": "my-app@10.0.0.5:2552", "path": "/system/cluster/sharding/region-cart", "proxy": false, "shards": [0, 1, 2, ..., 33] }, ... ], "shardHome": [ { "shard": 0, "regionKey": "my-app@10.0.0.5:2552" }, ... ]}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.
Metrics
Section titled “Metrics”GET /metrics
Section titled “GET /metrics”Opt-in via enableMetricsEndpoint: true.
GET /metrics→ 200 OKContent-Type: text/plain; version=0.0.4; charset=utf-8
# HELP actor_messages_processed_total ...# TYPE actor_messages_processed_total counteractor_messages_processed_total{class="Worker",path="..."} 12345...Prometheus text format. See Prometheus exporter.
Admin (opt-in)
Section titled “Admin (opt-in)”POST /cluster/leave
Section titled “POST /cluster/leave”Opt-in via enableLeaveEndpoint: true.
POST /cluster/leave→ 202 AcceptedleavingThe 202 body is the plain-text word leaving (not JSON) — the leave
is fire-and-forget.
Triggers graceful cluster-leave. The node transitions through
leaving → exiting → removed; 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.
POST /cluster/down
Section titled “POST /cluster/down”Opt-in via enableDownEndpoint: true.
POST /cluster/down{ "address": "actor-ts://my-app@10.0.0.5:2552" }
→ 202 Accepted{ "downed": "actor-ts://my-app@10.0.0.5:2552" }Returns 202 with { downed } when the member was downed, or 404
if the address is unknown or already terminal.
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
unreachablemembers that refuse to recover.
High-risk endpoint — gate behind auth + audit logs.
Custom routes
Section titled “Custom routes”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 system.http(port, { host }).bind(customRoutes);managementRoutes(system, cluster, options) returns the base
routes; combine with your own using concat. Useful for
adding app-specific admin endpoints alongside the standard set.
Response format
Section titled “Response format”The read endpoints (/health, /ready, /cluster/members,
/cluster/leader, /cluster/shards) and /cluster/down return
JSON. /metrics returns Prometheus text/plain, and
/cluster/leave returns the plain-text body leaving.
Errors are plain-text bodies (the framework’s complete(status, message)), not a structured object — e.g. a missing type query
param yields a 400 whose body is missing query param \type“.
Status codes follow HTTP conventions: 200 for reads, 202 Accepted
for the admin actions (/cluster/leave, /cluster/down), 4xx for
client errors (404 when a /cluster/down address is unknown), and
503 when the cluster or a health check is unavailable.
Authentication & IP allowlisting (#312)
Section titled “Authentication & IP allowlisting (#312)”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:
authwraps the privileged subset (/cluster/*,/metrics)./healthand/readystay anonymous — Kubernetes liveness/readiness probes can’t easily attach an Authorization header. SetauthProtectHealth: truewhen your deployment guarantees the probes can present credentials.ipAllowlistwraps EVERY endpoint including/healthand/ready. Network-level isolation is independent of who’s authenticated.
Failure modes:
- Missing / wrong
Authorizationheader →401 UnauthorizedwithWWW-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.
Where to next
Section titled “Where to next”- Management overview — the bigger picture.
- Health checks — custom check registration.
- Cluster overview — the
membership semantics behind the
/cluster/*endpoints. - Kubernetes deployment — the K8s recipe using these endpoints.
- Prometheus exporter — the metrics format details.
