@sdxc/health
Run dependency health checks and read application/health+json reports
- Installs with
- @sdxc/json-schema@sdxc/logger@sdxc/result
- Used by
- uptime, auth-saas, reader, blog, books, sdxc-api
- Source
- packages/health
Dependency health checks that answer in the application/health+json format, and a reader for
reports other services send.
Installation
npm add @sdxc/healthValidation runs on remix/data-schema from remix,
through @sdxc/json-schema.
Usage
Answer a health route
Register one probe per dependency, then answer the route with respond. Every probe runs in
parallel; the report is 200 while nothing fails and 503 once a critical probe does.
import { HealthCheck } from "@sdxc/health";
let health = new HealthCheck<{ db: Database }>({ serviceId: "shop", timeout: 2_000 });
health.probe("database", (ctx) => ctx.db.exec("SELECT 1"), { componentType: "datastore" });
health.probe("cache", () => env.CACHE.get("health"));
export default createAction(routes.health, (ctx) => health.respond(ctx));{
"status": "pass",
"serviceId": "shop",
"checks": {
"database:responseTime": [
{
"componentType": "datastore",
"status": "pass",
"observedValue": 4,
"observedUnit": "ms",
"time": "2026-10-24T12:00:00.000Z"
}
],
"cache:responseTime": [
{
"status": "pass",
"observedValue": 9,
"observedUnit": "ms",
"time": "2026-10-24T12:00:00.000Z"
}
]
}
}Probe a third-party service
A probe receives an AbortSignal that aborts at its timeout. A Response passes on 2xx, so a
probe can return fetch as is; critical: false turns its failure into a warn.
health.probe(
"payments",
(ctx, signal) =>
fetch("https://api.example.com/healthz", {
signal: AbortSignal.any([ctx.request.signal, signal]),
}),
{ critical: false, timeout: 5_000, affectedEndpoints: ["/checkout"] },
);Read another service's report
import { isHealthResponse, parseHealth } from "@sdxc/health";
import { isSuccess } from "@sdxc/result";
let response = await fetch("https://api.example.com/health");
if (isHealthResponse(response)) {
let report = parseHealth(await response.text());
if (isSuccess(report)) report.data.status; // "pass" | "warn" | "fail"
}Validate with the JSON Schema
import * as s from "@sdxc/json-schema";
import HEALTH_REPORT from "@sdxc/health/schema";
let report = s.parse(HEALTH_REPORT, json);
s.toJSONSchema(HEALTH_REPORT); // the document, for an OpenAPI response bodyThe same document ships as @sdxc/health/schema.json and is published at
https://sdxc.dev/schemas/health.json.
API
new HealthCheck<Context>(options?)
Options, all optional: timeout (ms per probe, default 2000), the report's serviceId,
description, version, releaseId, notes and links, maxAge (seconds sent as
Cache-Control: max-age, default 0), failStatus (the status of a fail, default 503)
and exposeErrors (put error messages in output, default false). Out-of-range values
throw a RangeError.
health.probe(name, probe, options?)
Registers probe(context, signal) as the check <name>:responseTime, replacing one of the same
name; a name with a colon throws a RangeError. It passes when it resolves, and fails when it
rejects, times out, or resolves to a non-2xx Response or a failed @sdxc/result. A response
that is itself a health report is judged by its status too: fail fails, warn warns. Options:
critical (default true), timeout, componentType, componentId, links and
affectedEndpoints. Returns the instance.
health.check(context) and health.respond(context)
check resolves to the report and never rejects; every check not passing is logged on the
current @sdxc/logger log with its error.
respond is that report as an application/health+json response.
parseHealth(body: string): Result<Health.Report, Error>
Validates a report's JSON text and normalizes every status (ok, up, error, down, any
case) to pass, warn or fail. Fails on a body that is not JSON or not a report.
isHealthResponse(response: Response): boolean
Whether the Content-Type is application/health+json, ignoring parameters and case.
HEALTH_MEDIA_TYPE
"application/health+json".
@sdxc/health/schema and @sdxc/health/schema.json
The format as an @sdxc/json-schema schema (default export), and as a static JSON Schema
2020-12 document. Both accept everything the format allows, from any service.
Types
Health.Report, Health.Check, Health.Status, Health.Probe, Health.Options and
Health.ProbeOptions.
Pattern: Fail When a Dependency Reports Itself Unhealthy
A service that also serves this format is judged by what it reports, not only by its status
code, so a dependency answering 200 with fail fails this check too.
import { HealthCheck } from "@sdxc/health";
let health = new HealthCheck({ serviceId: "storefront" });
health.probe("identity", (_, signal) => fetch("https://id.example.com/health", { signal }), {
componentType: "system",
});
let report = await health.check();
report.checks?.["identity:responseTime"]?.[0]?.output; // "reported fail" while identity is down