66## Problem
77
88Services built on this library need a ` /health ` endpoint that reports
9- overall health plus per-dependency status. The internal ` hii-generate-health-java `
10- library already provides the check-running machinery (` HealthCheckService ` ,
11- ` HealthCheck ` , ` HealthCheckResult ` , ` Status ` ) and a documented JSON shape:
9+ overall health plus per-dependency status. The expected wire format is:
1210
1311``` json
1412{
@@ -20,8 +18,9 @@ library already provides the check-running machinery (`HealthCheckService`,
2018```
2119
2220We want a ready-to-use ` HttpHandler ` in this repo that produces that exact
23- shape, ** without** taking a compile-time dependency on the health library.
24- Callers should be able to wire it up in one line.
21+ shape. The handler must not depend on any specific health-check provider —
22+ callers supply the data through a ` Supplier ` , so they can plug in whatever
23+ mechanism (off-the-shelf or in-house) computes their dependency statuses.
2524
2625## Goals
2726
@@ -32,21 +31,20 @@ Callers should be able to wire it up in one line.
3231 - Never propagates a probe failure as a 500 — a throwing ` Supplier ` yields
3332 ` Down ` + empty dependency list + 503.
34332 . Define small public records ` HealthOutcome ` and ` Dependency ` in
35- ` com.retailsvc.http ` that mirror the health library's data shape on the wire,
36- so this repo stays decoupled from the library .
34+ ` com.retailsvc.http ` that own the wire shape, so this library has no
35+ runtime or compile-time dependency on any specific health-check provider .
37363 . Reuse existing infrastructure (` MethodLimitedHandler ` , hand-rolled
3837 JSON rendering á la ` ProblemDetailRenderer ` ). No new third-party deps.
3938
4039## Non-goals
4140
42- - Direct integration with ` HealthCheckService ` (callers adapt the library's
43- ` HealthCheckResult ` to ` HealthOutcome ` in a one-line lambda; that adapter
44- lives in the consuming service, not here) .
45- - Caching of probe results (the health library already supplies
46- ` CachingHealthCheck ` ) .
41+ - Bundling or running health checks. Callers compute their own outcome
42+ (typically by adapting whatever check-runner they use into a
43+ ` HealthOutcome ` ) and pass it in via the ` Supplier ` .
44+ - Caching of probe results. If a caller's checks are expensive, they
45+ memoize on their side of the ` Supplier ` .
4746- A configurable wire format — the field names ` outcome ` , ` dependencies ` ,
48- ` id ` , ` status ` and the string values ` Up ` / ` Down ` are fixed to match the
49- library's documented contract.
47+ ` id ` , ` status ` and the string values ` Up ` / ` Down ` are fixed.
5048- Configurable Content-Type or status codes — fixed at ` application/json ` +
5149 200/503.
5250- An integration test — unit coverage is sufficient; ` MethodLimitedHandler `
@@ -76,8 +74,8 @@ public record Dependency(String id, String status) {
7674}
7775```
7876
79- ` HealthOutcome.isUp() ` is case-insensitive so callers that pass through a
80- library-style "Up" or a custom-cased "UP" both work .
77+ ` HealthOutcome.isUp() ` is case-insensitive so callers that pass ` "Up" ` ,
78+ ` "UP" ` , or ` "up" ` all map to a healthy 200 response .
8179
8280### Public API — ` Handlers.healthHandler `
8381
@@ -117,26 +115,25 @@ remaining control characters below `0x20`.
117115### Caller-side wiring (illustrative, not part of this repo)
118116
119117``` java
120- HealthCheckService service = new HealthCheckService ();
121- // register checks…
122-
123118server = OpenApiServer . builder()
124119 .spec(spec)
125120 .jsonMapper(mapper)
126121 .handlers(operationHandlers)
127122 .addHandler(" /health" , Handlers . healthHandler(() - > {
128- HealthCheckResult r = service. check();
129- return new HealthOutcome (
130- r. outcome(),
131- r. dependencies(). stream()
132- .map(s - > new Dependency (s. id(), s. status()))
133- .toList());
123+ // Caller computes per-dependency statuses however they choose
124+ // and adapts the result into HealthOutcome / Dependency.
125+ List<Dependency > deps = List . of(
126+ new Dependency (" jdbc" , checkDatabase() ? " Up" : " Down" ),
127+ new Dependency (" cache" , checkCache() ? " Up" : " Down" ));
128+ String outcome = deps. stream(). allMatch(d - > " Up" . equalsIgnoreCase(d. status()))
129+ ? " Up" : " Down" ;
130+ return new HealthOutcome (outcome, deps);
134131 }))
135132 .build();
136133```
137134
138- The adapter lambda is the only place that knows about both libraries — which
139- is exactly where the coupling belongs.
135+ The ` Supplier ` is the only place that knows how to compute health, which is
136+ exactly where any third-party integration belongs.
140137
141138## Error handling
142139
0 commit comments