HealthModule
Reports this service's health as one field of a Health entity shared with every other service in the composition.
Compose it into each service that should be reportable -- every instance of every service, since the check answers for the instance that received the query -- giving each one its own field name:
new HealthModule({
name: "products",
checks: {
engine: () => client.ping(),
cache: () => cache.get("health"),
},
});
A single query then reports the whole deployment, which is what makes this usable as a promotion gate:
{ health { products { ok release } checkout { ok release } } }
Two HTTP routes carry the same information for callers that are not the router, and they answer different questions:
/healthcheckruns no checks and answers 200 with the component name and the running release for as long as the process can serve a request. This is the liveness probe, and the reason it checks nothing is that a probe fails on a timeout as surely as on a status code./readinessruns the checks and answers 503 when any of them failed. This is the one for a startup probe and for a deploy gate that can only read a status code.
A service that serves no GraphQL at all -- a payment provider, a sitemap
builder, a search indexer -- composes this with graphql: false and gets the
routes without becoming a subgraph.
This is deliberately not the router's own liveness or readiness probe: those answer for the router's HTTP layer and its selected supergraph, never reach a service, and keep reporting healthy while a service behind them is broken.
The report carries the running build so a gate can tell it reached the instances it is about to promote rather than the ones still serving traffic.
import { HealthModule } from "@evolve-framework/core";new HealthModule(options: HealthModuleOptions)| Option | Type | Description |
|---|---|---|
name | string | The field this service contributes to the shared |
release? | string | The build this instance runs, reported as |
check? | HealthCheck | Whether the service itself is healthy, for a reason that is not one of its
dependencies. Its failure message lands on |
checks? | Record<string, HealthCheck | HealthCheckDefinition> | The dependencies to check, keyed by the name to report them under. They run concurrently on every query. MoreA bare function is reported without counting towards the verdict. Wrap it
as
|
readinessRoute? | string | false | Where to serve the full report over plain HTTP, or MoreIt runs the checks and answers 200 when the service is healthy, 503 when it is not -- so unlike the GraphQL query it can be gated on a status code, where a federated response reports a partial failure as a 200 with a populated errors list. Point startup probes and deploy gates here. Not a liveness probe. It reports on the service's dependencies, so a
dependency outage answers 503 and would have every instance restarted for a
fault none of them can fix. Liveness belongs on A readiness probe is worth a thought too, for the same reason in a quieter form: an outage of something every instance shares takes the whole deployment out of rotation, which turns a degraded service into an absent one. What this route is unambiguously right for is a startup probe -- invalid credentials or a missing scope then keep a new build from ever receiving traffic, which is the failure it can actually rule out. |
livenessRoute? | string | false | Where to serve the cheap liveness report, or MoreIt answers 200 with the component name and the running release for as long as this process can serve a request, and deliberately runs no checks: a probe fails on a timeout as surely as on a status code, so a route meant to say "this process is alive" must not wait on anything that can hang. |
graphql? | boolean | Whether to contribute the MoreSet it to |
timeout? | number | How long a single check may take before it counts as failed, in milliseconds. Defaults to 2000. MoreA check that never settles is the case this exists for: without it a hung dependency hangs the health query itself, and a deploy gate waiting on the query learns nothing until the router's own timeout fires. |
Extends AbstractModule<unknown>.

