Package com.shri.restinpeace
Class RIP
java.lang.Object
com.shri.restinpeace.RIP
Entry point for REST-in-peace: turns an annotated
@RestClient
interface into a working HTTP client backed by a JDK dynamic proxy, via
getClient(Class).-
Method Summary
Modifier and TypeMethodDescriptionstatic voidaddCallAdapterFactory(CallAdapterFactory factory) Registers a globalCallAdapterFactory, letting a method declare a return type RIP itself has no built-in support for (e.g.static voidaddInterceptor(RequestInterceptor interceptor) Registers a global hook into every request/response made through RIP - seeRequestInterceptorfor what it can and can't do.static voidRegisters a globalPaginatedCallAdapterFactory, letting a@Paginatedmethod declare a return type RIP itself has no built-in support for (e.g.static voidRemoves every registeredCallAdapterFactory.static voidRemoves all registered interceptors.static voidRemoves every registeredPaginatedCallAdapterFactory.static <T> TValidatesrestClientand returns a proxy implementing it, where each method call issues the HTTP request its annotations describe.static <T> TgetClient(Class<T> restClient, RipClientConfig config) Same asgetClient(Class), but resolves the base URL, connect/read timeout, and proxy fromconfiginstead of the interface's@BaseUrland the shared client's global config - for a@RestClientwhose environment (base URL, timeout, proxy) differs from every other client's.static <T> TSame asgetClient(Class), but every relative method URL is resolved againstbaseUrlinstead of the interface's@BaseUrl- for a base URL that's only known at runtime (e.g.static voidRemoves one previously registered globalCallAdapterFactoryby identity; a no-op if it was never registered (or already removed).static voidremoveInterceptor(RequestInterceptor interceptor) Removes one previously registered global interceptor by identity, leaving every other registered interceptor - including other instances of the same class - untouched.static voidRemoves one previously registered globalPaginatedCallAdapterFactoryby identity; a no-op if it was never registered (or already removed).static voidSets the shared defaultCachefor response caching, used by every client not built with aRipClientConfigthat sets its own viaRipClientConfig.Builder.cache(Cache).static voidsetCacheKeyIncludesQueryString(boolean includeQueryString) Sets whether the cache key includes the request's query string, for every client not built with aRipClientConfigthat sets its own viaRipClientConfig.Builder.cacheKeyIncludesQueryString(boolean).static voidsetNegativeCacheTtlMillis(long ttlMillis) Sets the shared default negative-cache TTL, for every client not built with aRipClientConfigthat sets its own viaRipClientConfig.Builder.negativeCacheTtlMillis(long).static voidsetObjectMapper(kong.unirest.ObjectMapper objectMapper) Sets theObjectMapperused to (de)serialize JSON request/response bodies for every client sharing the app-wide static Unirest client (i.e.static voidOpt-in: makes a CompletableFuture-returning call use daemon threads for Unirest's async client, so a short-lived program can exit on its own after an async call instead of hanging on non-daemon I/O threads.
-
Method Details
-
getClient
ValidatesrestClientand returns a proxy implementing it, where each method call issues the HTTP request its annotations describe.- Type Parameters:
T- the rest client interface type- Parameters:
restClient- an interface annotated with@RestClient- Returns:
- a proxy instance implementing
restClient - Throws:
RestInPeaceException- if the interface is missing@RestClientor fails validation
-
getClient
Same asgetClient(Class), but every relative method URL is resolved againstbaseUrlinstead of the interface's@BaseUrl- for a base URL that's only known at runtime (e.g. an app that deploys the same@RestClientinterface against a different environment per deployment, read from an env var or config file). An absolute method URL still ignores this, same as it ignores@BaseUrl;@BaseUrlon the interface is itself optional when every relative method URL is covered bybaseUrlhere.- Type Parameters:
T- the rest client interface type- Parameters:
restClient- an interface annotated with@RestClientbaseUrl- the runtime base URL to resolve relative method URLs against, ornullto require@BaseUrlon the interface instead- Returns:
- a proxy instance implementing
restClient - Throws:
RestInPeaceException- if the interface is missing@RestClientor fails validation
-
getClient
Same asgetClient(Class), but resolves the base URL, connect/read timeout, and proxy fromconfiginstead of the interface's@BaseUrland the shared client's global config - for a@RestClientwhose environment (base URL, timeout, proxy) differs from every other client's. SeeRipClientConfig.- Type Parameters:
T- the rest client interface type- Parameters:
restClient- an interface annotated with@RestClientconfig- the per-client settings- Returns:
- a proxy instance implementing
restClient - Throws:
RestInPeaceException- if the interface is missing@RestClientor fails validation
-
useDaemonThreadsForAsync
public static void useDaemonThreadsForAsync()Opt-in: makes a CompletableFuture-returning call use daemon threads for Unirest's async client, so a short-lived program can exit on its own after an async call instead of hanging on non-daemon I/O threads. Not the default, since it reconfigures Unirest's shared global client - call this once at startup, before building any client, only if your app doesn't already configure Unirest's async client itself.Covers every client sharing the app-wide static
Unirestclient and everyRipClientConfig-backed client with its own dedicatedUnirestInstanceconstructed after this call - a config'd client already built before this runs keeps whatever async client it was constructed with, the same "call once at startup, before building any client" requirement every other global RIP setting (setObjectMapper(kong.unirest.ObjectMapper),setCache(com.shri.restinpeace.cache.Cache)) already has. -
setObjectMapper
public static void setObjectMapper(kong.unirest.ObjectMapper objectMapper) Sets theObjectMapperused to (de)serialize JSON request/response bodies for every client sharing the app-wide static Unirest client (i.e. every client not built with aRipClientConfigthat sets its own timeout/proxy/objectMapper). RIP defaults to Unirest's own Gson-backedkong.unirest.JsonObjectMapper- call this to use Jackson or another mapper instead. ARipClientConfig-configured client with its own dedicated Unirest instance needsRipClientConfig.Builder.objectMapper(ObjectMapper)instead; this method has no effect on it.- Parameters:
objectMapper- the mapper to use
-
setCache
Sets the shared defaultCachefor response caching, used by every client not built with aRipClientConfigthat sets its own viaRipClientConfig.Builder.cache(Cache). OnlyGETresponses are ever cached, and only those the server itself marks cacheable viaCache-Control/ETag/Last-Modified- no cache configured (the default) means no caching at all, byte-for- byte today's behavior.- Parameters:
cache- the shared default cache, ornullto disable caching for every client without its ownCache
-
setCacheKeyIncludesQueryString
public static void setCacheKeyIncludesQueryString(boolean includeQueryString) Sets whether the cache key includes the request's query string, for every client not built with aRipClientConfigthat sets its own viaRipClientConfig.Builder.cacheKeyIncludesQueryString(boolean). Defaults totrue-/items?page=1and/items?page=2are cached separately, matching today's behavior. Turn this off for an endpoint whose query params don't affect the response (e.g. an analytics/tracking param), so every query-string variant of the same path shares one cache entry instead - trading that precision for a higher hit rate. Has no effect on a client with noCacheconfigured at all.- Parameters:
includeQueryString- whether the cache key includes the query string
-
setNegativeCacheTtlMillis
public static void setNegativeCacheTtlMillis(long ttlMillis) Sets the shared default negative-cache TTL, for every client not built with aRipClientConfigthat sets its own viaRipClientConfig.Builder.negativeCacheTtlMillis(long). A confirmed404is then stored forttlMillis, regardless of whether the response itself carries anyCache-Control/ETag/Last-Modifiedat all - unlike every other cached status, which is only ever stored when the server's own headers say so - so a client stops hammering a downstream for a resource it already confirmed doesn't exist. Not called at all (the default) means no negative caching, byte-for-byte today's behavior. Has no effect on a client with noCacheconfigured at all, and is skipped the same way by@NoCache.- Parameters:
ttlMillis- how long a confirmed404stays negatively cached, in milliseconds; must be positive
-
addInterceptor
Registers a global hook into every request/response made through RIP - seeRequestInterceptorfor what it can and can't do.- Parameters:
interceptor- the interceptor to register
-
removeInterceptor
Removes one previously registered global interceptor by identity, leaving every other registered interceptor - including other instances of the same class - untouched. For an embedder (e.g. a dependency-injection framework's auto-configuration) that registers its own beans as global interceptors on startup and needs to reverse exactly those on shutdown, sinceclearInterceptors()would also wipe out interceptors some other, still-live part of the same JVM registered (this registry is shared process-wide, not scoped to any one caller).- Parameters:
interceptor- the interceptor instance to remove; a no-op if it was never registered (or already removed)
-
clearInterceptors
public static void clearInterceptors()Removes all registered interceptors. Mainly useful for tests - removes every interceptor registered by anyone, not just the caller's own; seeremoveInterceptor(RequestInterceptor)for a narrower alternative. -
addCallAdapterFactory
Registers a globalCallAdapterFactory, letting a method declare a return type RIP itself has no built-in support for (e.g. Project Reactor'sMono<T>/Flux<T>, via the separaterest-in-peace-reactormodule). Call once at startup, before building any client - the same "configure globals first" requirementsetObjectMapper(kong.unirest.ObjectMapper)/setCache(com.shri.restinpeace.cache.Cache)/useDaemonThreadsForAsync()already have, since a factory needs to be registered beforeReflectiveRestClientValidatorvalidates a method claiming it. Seedocs/design/reactor-call-adapter.md.- Parameters:
factory- the factory to register
-
removeCallAdapterFactory
Removes one previously registered globalCallAdapterFactoryby identity; a no-op if it was never registered (or already removed).- Parameters:
factory- the factory instance to remove
-
clearCallAdapterFactories
public static void clearCallAdapterFactories()Removes every registeredCallAdapterFactory. Mainly useful for tests. -
addPaginatedCallAdapterFactory
Registers a globalPaginatedCallAdapterFactory, letting a@Paginatedmethod declare a return type RIP itself has no built-in support for (e.g. Project Reactor'sFlux<T>, via the separaterest-in-peace-reactormodule) - the pagination-aware counterpart ofaddCallAdapterFactory(com.shri.restinpeace.CallAdapterFactory). Call once at startup, before building any client, for the same reason. Seedocs/design/reactor-call-adapter.mdยง7.2.- Parameters:
factory- the factory to register
-
removePaginatedCallAdapterFactory
Removes one previously registered globalPaginatedCallAdapterFactoryby identity; a no-op if it was never registered (or already removed).- Parameters:
factory- the factory instance to remove
-
clearPaginatedCallAdapterFactories
public static void clearPaginatedCallAdapterFactories()Removes every registeredPaginatedCallAdapterFactory. Mainly useful for tests.
-