What is RepositoryDetectionStrategy in Spring Data REST, what are its modes, and how do you configure it?
answer
- DEFAULT = public + honors exported=false
- ALL = everything, ignores visibility + annotations
- ANNOTATED = opt-in whitelist
- VISIBILITY = public interfaces only
- property spring.data.rest.detection-strategy / RepositoryRestConfigurer
basics
~20 sRepositoryDetectionStrategy decides which repositories Spring Data REST exposes. Modes: DEFAULT (all public repos, respecting exported=false), ALL (every repo, ignoring visibility and annotations), ANNOTATED (only repos annotated for export), and VISIBILITY (only public repos). Set it via the spring.data.rest.detection-strategy property or a RepositoryRestConfigurer.
solid answer
~40 s`RepositoryDetectionStrategy` is the policy SDR consults to decide which discovered repositories become REST resources. The built-in `RepositoryDetectionStrategies` enum has four values: **DEFAULT** exposes all *public* repository interfaces while honoring `@(Repository)RestResource(exported=false)`; **ALL** exposes every repository regardless of Java visibility or annotations (so it ignores `exported=false`); **ANNOTATED** exposes *only* repositories explicitly annotated with `@RepositoryRestResource` whose exported flag isn't false — an opt-in whitelist; **VISIBILITY** exposes only public repositories (like DEFAULT but purely visibility-driven). You configure it either declaratively with `spring.data.rest.detection-strategy=default|all|annotated|visibility`, or programmatically by implementing `RepositoryRestConfigurer` and calling `config.setRepositoryDetectionStrategy(...)`. ANNOTATED is the go-to for locking down which repositories are public — nothing is exposed unless you deliberately annotate it.
code
java · 17 lines// Option A — declarative (application.properties)
// spring.data.rest.detection-strategy=annotated
// Option B — programmatic, with an explicit opt-in whitelist
@Component
class RestConfig implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(
RepositoryRestConfiguration config, CorsRegistry cors) {
config.setRepositoryDetectionStrategy(
RepositoryDetectionStrategies.ANNOTATED); // only annotated repos exposed
}
}
// Under ANNOTATED, only this repo is public; unannotated repos stay private.
@RepositoryRestResource(path = "people")
public interface PersonRepository extends JpaRepository<Person, Long> { }go deeper
Know that some setting controls which repositories become endpoints and that all public ones are exposed by default.
Name the four modes and that DEFAULT respects exported=false.
Explain each mode precisely, that ALL ignores exported=false, and both configuration paths (property + RepositoryRestConfigurer).
Standardize on ANNOTATED (or package-private repos) for a governed public surface; treat detection strategy as a security control and audit it in reviews.
**What it is.** After Spring Data creates repository beans, Spring Data REST must decide *which* of them to publish as HTTP resources. That decision is delegated to a `RepositoryDetectionStrategy` — a strategy interface with one method that answers 'should this repository be exported?' SDR ships an enum of ready-made policies, `RepositoryDetectionStrategies`. **The four modes (memorize these).** - **DEFAULT** — the out-of-the-box behavior. Exposes all repositories whose *interface is public*, and it **respects** `@RepositoryRestResource(exported=false)` / `@RestResource(exported=false)`. So: public + not opted-out. - **ALL** — exposes **every** repository regardless of Java visibility (even package-private) **and ignores annotations**, so a repo marked `exported=false` is still published. The most permissive; rarely what you want in production. - **ANNOTATED** — exposes **only** repositories carrying `@(Repository)RestResource` with the exported flag not set to false. This is an explicit **whitelist/opt-in** model: unannotated repositories stay private. Best for a controlled public surface. - **VISIBILITY** — exposes only *public* repository interfaces, based purely on Java visibility. Similar to DEFAULT but framed as 'visibility decides'; making a repository package-private hides it. **Interaction with exported=false.** DEFAULT, ANNOTATED, and VISIBILITY all honor `exported=false`; **ALL does not**. This is a classic trap — teams add `exported=false` to hide a repo but leave the strategy on ALL and the repo is still public. **How to configure.** 1. **Property (Boot):** `spring.data.rest.detection-strategy=annotated` (values: `default`, `all`, `annotated`, `visibility`). 2. **Programmatic:** implement `RepositoryRestConfigurer` and override `configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors)`, calling `config.setRepositoryDetectionStrategy(RepositoryDetectionStrategies.ANNOTATED)`. You can also supply a custom `RepositoryDetectionStrategy` implementation for bespoke rules. **Using visibility as the control.** Under DEFAULT/VISIBILITY, simply declaring a repository interface *package-private* (dropping `public`) prevents its export — a lightweight way to keep helper repositories internal without annotations. **When to use which.** Prefer **ANNOTATED** when you want an explicit, auditable list of public repositories (safest default for real services). Use **DEFAULT/VISIBILITY** for rapid internal tools where exposing everything public is acceptable. Avoid **ALL** unless you truly want to expose absolutely everything, since it defeats both visibility and `exported=false` controls. **Gotchas.** (1) Switching to ANNOTATED silently un-exposes every repository you hadn't annotated — endpoints 404 after the change. (2) ALL ignoring `exported=false` is a security footgun. (3) The property name is `spring.data.rest.detection-strategy`; the enum lives in `RepositoryDetectionStrategies` (plural) even though the interface is `RepositoryDetectionStrategy` (singular).
- Which strategy gives you an explicit whitelist of exposed repositories?ANNOTATED — only repositories annotated with @RepositoryRestResource (exported not false) are exposed; everything else stays private, making the public surface auditable.
- Under the DEFAULT strategy, how can you hide a repository without any annotation?Make its interface package-private (remove the public modifier). DEFAULT/VISIBILITY only export public repositories, so a non-public interface is not exposed.
saying these in an interview costs you the question
- Believing exported=false always hides a repo (ALL ignores it)
- Confusing the singular interface RepositoryDetectionStrategy with the enum RepositoryDetectionStrategies
- Thinking ANNOTATED is the default (DEFAULT is)