Skip to main content

RestContext

Outdated examples (10.0)

Examples on this page using RestContext.Builder (constructor injection or @RestInit parameter injection) is pre-10.0 and kept only for historical context. The Builder-injection protocol was removed; migrate to @Rest(...) / @RestOp(...) attributes, @Bean(name="...") bean suppliers, and new RestContext(RestContextInit) for programmatic bootstrap. See the V10 Migration Guide.

The RestContext object is the workhorse class for all of the configuration of a single REST resource class. It's by-far the most important class in the REST API. Every class annotated with @Rest ends up with an instance of this object.

The object itself is read-only and unchangeable and is initialized from the resource/method annotations plus injected beans in the resource bean store.

In 10.0+, configuration is annotation-driven (@Rest(...), @RestOp(...), @RestGet(...), etc.) with optional @Bean(name="...") bean suppliers for programmatic overrides.

This class is vast. Combined with RestOpContext (which is the equivalent per-method context), these classes define the entire configuration and workflow of the REST API.

For direct programmatic bootstrap, use RestContext.Args with new RestContext(init). This replaces the legacy RestContext.create(...).init(...).build() factory chain.

10.0+ guidance

Prefer these configuration surfaces:

  • @Rest(...) for resource-level settings.
  • @RestOp(...) / verb annotations for operation-level settings.
  • @Bean(name="...") bean suppliers for programmatic overrides.
note

The builders or built objects above can also be defined as injected beans defined in a Spring Configuration if you wish to do all your app configuration Spring-style. This is described in detail in the juneau-rest-server-springboot documentation.

The lifecycle methods are still annotation-driven via @RestInit, @RestPreCall, @RestPostCall, @RestStartCall, and @RestDestroy.

RestContextProperties — env-driven defaults via @ConfigProperties (10.0.0)​

As of 10.0.0, the env-driven defaults behind most RestContext.* settings — the values consulted when a @Rest(...) attribute is left unset — are resolved as a single bound object, RestContextProperties, rather than as 15 separate @Value fields. RestContextProperties is declared @ConfigProperties(prefix = "RestContext") (see @ConfigProperties Annotation Basics for how the annotation and its underlying binder work), and it's the framework's own pilot for that feature.

Practically, this changes nothing about how you configure these settings — a RestContext.* key is still resolved from the same places it always was:

  • A resource's @Rest(config=...) file, via the config's PropertySource registration in the resource's BeanStore.
  • Environment variables and system properties (relaxed key matching applies, so RestContext.clientVersionHeader, REST_CONTEXT_CLIENT_VERSION_HEADER, and rest.context.client.version.header-style dotted forms are all equivalent).
  • Any other registered PropertySource.

What's new is that the bound instance itself is directly accessible — either from the context:

RestContextProperties props = ctx.getRestContextProperties();

or from the resource's bean store, since the bind auto-registers it (see Auto-registration in the BeanStore):

RestContextProperties props = ctx.getBeanStore().getBean(RestContextProperties.class).orElseThrow();

Every existing public getter on RestContext (isRenderResponseStackTraces(), getClientVersionHeader(), getUriRelativity(), etc.) keeps its exact signature and blending behavior with @Rest-annotation overrides — they're unaffected thin wrappers; only the source of the default half of that computation moved from a private @Value field to RestContextProperties.

Two settings are intentionally not part of RestContextProperties: RestContext.uriAuthority and RestContext.uriContext remain standalone @Value("${RestContext.uriAuthority}") / @Value("${RestContext.uriContext}") Optional<String> fields directly on RestContext, because they carry a null-vs-empty distinction that @ConfigProperties' current raw-type-only conversion can't express (see the current limitations of @ConfigProperties).

Leniency improvement for present-but-empty booleans

Under the pre-10.0.0 @Value boolean fields, a present-but-empty value (e.g. RestContext.eagerInit=) threw BeanCreationException. As of 10.0.0, RestContextProperties carries every boolean setting as a raw string and RestContext parses it leniently, so a present-but-empty value now resolves to false instead of throwing — for all 8 boolean settings (disableContentParam, renderResponseStackTraces, problemDetails, virtualThreads, responseTraceparent, mdcAsyncPropagation, eagerInit, lazyChildren). See the 10.0.0 release notes for details.