skip to content

What is the Actuator discovery index at /actuator, and how do you find out which endpoints your running app actually exposes?

level: juniorimportance: must knowfreq 45%

answer

  1. GET /actuator = HAL index
  2. _links: id -> href
  3. templated = URI template
  4. only enabled + web-exposed appear
  5. health exposed by default

basics

~10 s

GET /actuator returns a JSON document with a _links section. Each entry maps an endpoint id (like health, metrics, beans) to its URL. It's the menu of endpoints currently exposed over the web.

solid answer

~40 s

Spring Boot Actuator serves a discovery index at the base path `/actuator`. It returns a HAL-style JSON document whose `_links` object lists every web-exposed endpoint by id together with its `href` and whether it is `templated`. Only endpoints that are both enabled and web-exposed appear, so it's the authoritative runtime view of what's reachable. The catalog of standard endpoints includes `health`, `info`, `metrics`, `env`, `beans`, `mappings`, `configprops`, `conditions`, `scheduledtasks`, and `caches`, among others. `health` is exposed by default; the rest must be opted into. The index itself is what tooling and humans use to navigate; each `href` is an absolute URL you can GET directly. Templated links (like `metrics/{requiredMetricName}`) show a URI template you fill in.

code

java · 15 lines
java
// Example response body of  GET http://localhost:8080/actuator
// (only endpoints that are enabled AND web-exposed are listed)
{
  "_links": {
    "self":    { "href": "http://localhost:8080/actuator", "templated": false },
    "health":  { "href": "http://localhost:8080/actuator/health", "templated": false },
    "health-path": {
      "href": "http://localhost:8080/actuator/health/{*path}", "templated": true
    },
    "metrics": { "href": "http://localhost:8080/actuator/metrics", "templated": false },
    "metrics-requiredMetricName": {
      "href": "http://localhost:8080/actuator/metrics/{requiredMetricName}", "templated": true
    }
  }
}

go deeper

for a junior

Know that GET /actuator lists exposed endpoints via _links, and that most endpoints are off by default.

for a middle

Explain templated links and that the index reflects live enable+expose state, not the full catalog.

for a senior

Contrast web (HAL index) vs JMX (MBeans) discovery, and note base-path relocation keeps ids stable.

for a principal

Discuss the index as an ops contract across environments and why prod typically exposes a minimal subset.

**Actuator** is Spring Boot's production-monitoring subsystem. It exposes a set of HTTP (or JMX) **endpoints** under a base path, `/actuator` by default. Each endpoint has a short **id** (`health`, `metrics`, etc.). **The discovery index.** A `GET /actuator` (with no id) returns the *discovery index* — a JSON document in **HAL** style (Hypertext Application Language). Its shape is: ```json { "_links": { "self": { "href": "http://localhost:8080/actuator", "templated": false }, "health": { "href": "http://localhost:8080/actuator/health", "templated": false }, "metrics": { "href": "http://localhost:8080/actuator/metrics", "templated": false }, "metrics-requiredMetricName": { "href": "http://localhost:8080/actuator/metrics/{requiredMetricName}", "templated": true } } } ``` Key points: - **`_links`** is a map of *relation name → link object*. The relation name is essentially the endpoint id (with a suffix when an endpoint has a path-variable variant). - **`href`** is the full URL to GET. - **`templated: true`** means the `href` contains a `{placeholder}` (a URI template, e.g. `metrics/{requiredMetricName}`) that you substitute before calling. - **`self`** points back at the index. **What shows up.** An endpoint appears in the index only if it is **enabled** *and* **exposed over the web**. Exposure and enablement are configured with `management.*` properties (that configuration belongs to the Spring Boot starter/config topic, not here) — but the *effect* you observe is: by default only `health` is web-exposed, so a fresh app's index is nearly empty. Once more endpoints are exposed, they each get a `_links` entry. This makes the index the single source of truth for 'what is actually reachable right now' — more reliable than guessing from docs, because it reflects the live configuration. **The standard endpoint catalog** (the ones this leaf covers): `health` (app/dependency health), `info` (arbitrary app info), `metrics` (Micrometer metric snapshots), `env` (Spring `Environment` property sources), `beans` (the bean graph), `mappings` (request mappings), `configprops` (`@ConfigurationProperties` bound values), `conditions` (auto-configuration condition report), `scheduledtasks` (`@Scheduled` inventory), and `caches` (Spring cache inventory). Others exist (`loggers`, `threaddump`, `heapdump`, `httpexchanges`, `prometheus`, `shutdown`, `flyway`/`liquibase`) but the ones above are the core catalog. **Gotchas.** - If you changed the base path (e.g. to `/manage`), the index moves too — the *ids* stay the same, only the prefix changes. - The index is not an authentication or authorization gate; it merely lists exposed endpoints. Anything listed is callable subject to your security config. - The `templated` links can't be GET-ed as-is; you must fill the placeholder. - Under JMX (rather than web), there is no HTTP index — endpoints appear as MBeans instead. **When to use.** During debugging or ops, hitting `/actuator` first tells you exactly which endpoints are live without reading config files, which is invaluable across environments where exposure differs (dev exposes many, prod exposes few).

  • Why might /actuator/beans return 404 even though /actuator/health works?
    Because only `health` is web-exposed by default. `beans` is a valid endpoint but must be explicitly added to the web exposure set before it appears in the index and becomes reachable; otherwise you get 404.
  • What does `templated: true` mean for a link?
    The `href` contains a URI-template placeholder (e.g. `metrics/{requiredMetricName}`) that you must substitute with a real value before issuing the request; you cannot GET the templated URL verbatim.

saying these in an interview costs you the question

  • Thinking every standard endpoint is reachable by default (only health is web-exposed by default)
  • Believing the index performs authentication or hides secured endpoints
  • Trying to GET a templated href without filling the placeholder

context