Deprecated
Please head over to zalando/riptide and use the riptide-spring-boot-starter
instead.
Migration
Please follow these steps to migrate from Put it to REST! to the Riptide Spring Boot Starter:
- Change
rest
key toriptide
- Change
connection-timeout
toconnect-timeout
- Remove
plugins
and replaceoriginal-stack-trace
withpreserve-stack-trace
temporary-exception
withdetect-transient-faults
- No hystrix support, use failsafe, if applicable
- Different defaults
- Maximum connections per route was increased from 2 to 20
- Thread pool has a bounded queue by default and a size of 0
Put it to REST!
put to rest verb: to finish dealing with something and forget about it
Put it to REST! is a library that seamlessly integrates various REST- and HTTP-related client-side tools in the easiest and convenient way possible. It solves a recurring problem of bootstrapping and wiring different libraries together whenever interaction with a remote service is required. Spinning up new clients couldn't get any easier!
- Technology stack: Spring Boot
- Status: Beta
Example
rest.clients:
example:
base-url: http://example.com
oauth.scopes:
- example.read
@RestClient("example")
private Rest example;
Features
- Seamless integration of:
- Riptide
- Logbook
- Tracer
- Tokens (plus interceptor)
- Jackson 2
- HttpClient
- optional gzipping of request body
- optional pinning of a trusted keystore
- Hystrix
- Spring Boot Auto Configuration
- Sensible defaults
Dependencies
- Java 8
- Any build tool using Maven Central, or direct download
- Spring Boot
- Riptide
- Logbook
- Tracer
- Tokens
- Apache HTTP Client
- Hystrix
Installation
Add the following dependency to your project:
<dependency>
<groupId>org.zalando</groupId>
<artifactId>put-it-to-rest</artifactId>
<version>${put-it-to-rest.version}</version>
</dependency>
If you want OAuth support you need to additionally add stups-spring-oauth2-support to your project. It comes with Tokens equipped.
<!-- if you need OAuth support additionally add: -->
<dependency>
<groupId>org.zalando.stups</groupId>
<artifactId>stups-http-components-oauth2</artifactId>
<version>$stups-http-components-oauth2.version}{</version>
</dependency>
Configuration
You can now define new REST clients and override default configuration in your application.yml
:
rest:
defaults:
connection-timeout: 1 seconds
socket-timeout: 2 seconds
connection-time-to-live: 30 seconds
max-connections-per-route: 16
max-connections-total: 16
plugins:
- original-stack-trace
oauth:
access-token-url: https://auth.example.com
credentials-directory: /secrets
scheduling-period: 10 seconds
connection-timeout: 1 second
socket-timeout: 1500 milliseconds
clients:
example:
base-url: https://example.com
connection-timeout: 2 seconds
socket-timeout: 3 seconds
oauth.scopes:
- uid
- example.read
plugins:
- original-stack-trace
- temporary-exception
- hystrix
compress-request: true
trusted:
base-url: https://my.trusted.com
keystore:
path: trusted.keystore
password: passphrase
Clients are identified by a Client ID, for instance example
in the sample above. You can have as many clients as you want.
For a complete overview of available properties, they type and default value please refer to the following table:
Configuration | Type | Required | Default |
---|---|---|---|
rest.defaults.connection-timeout |
TimeSpan |
no | 5 seconds |
rest.defaults.socket-timeout |
TimeSpan |
no | 5 seconds |
rest.defaults.connection-time-to-live |
TimeSpan |
no | 30 seconds |
rest.defaults.max-connections-per-route |
int |
no | 2 |
rest.defaults.max-connections-total |
int |
no | maximum of 20 and per route |
rest.defaults.plugins |
List<String> |
no | [original-stack-trace] |
rest.oauth.access-token-url |
URI |
no | env var ACCESS_TOKEN_URL |
rest.oauth.credentials-directory |
Path |
no | env var CREDENTIALS_DIR |
rest.oauth.scheduling-period |
TimeSpan |
no | 5 seconds |
rest.oauth.connetion-timeout |
TimeSpan |
no | 1 second |
rest.oauth.socket-timeout |
TimeSpan |
no | 2 seconds |
rest.oauth.connection-time-to-live |
TimeSpan |
no | see rest.defaults.connection-time-to-live |
rest.clients.<id>.base-url |
URI |
no | none |
rest.clients.<id>.connection-timeout |
TimeSpan |
no | see rest.defaults.connection-timeout |
rest.clients.<id>.socket-timeout |
TimeSpan |
no | see rest.defaults.socket-timeout |
rest.clients.<id>.connection-time-to-live |
TimeSpan |
no | see rest.defaults.connection-time-to-live |
rest.clients.<id>.max-connections-per-route |
int |
no | see rest.defaults.max-connections-per-route |
rest.clients.<id>.max-connections-total |
int |
no | see rest.defaults.max-connections-total |
rest.clients.<id>.oauth |
no | none, disables OAuth2 if omitted | |
rest.clients.<id>.oauth.scopes |
List<String> |
no | none |
rest.clients.<id>.plugins |
List<String> |
no | [original-stack-trace] |
rest.clients.<id>.compress-request |
boolean |
no | false |
rest.clients.<id>.keystore.path |
String |
no | none |
rest.clients.<id>.keystore.password |
String |
no | none |
Usage
After configuring your clients, as shown in the last section, you can now easily inject them:
@RestClient("example")
private Rest example;
All beans that are created for each client use the Client ID, in this case example
, as their qualifier.
Besides Rest
, you can also alternatively inject any of the following types per client directly:
RestTemplate
AsyncRestTemplate
ClientHttpRequestFactory
AsyncClientHttpRequestFactory
HttpClient
ClientHttpMessageConverters
AsyncListenableTaskExecutor
A global AccessTokens
bean is also provided.
Trusted Keystore
A client can be configured to only connect to trusted hosts (see Certificate Pinning) by configuring the keystore
key. Use keystore.path
to refer to a JKS keystore on the classpath/filesystem and (optionally) specify the passphrase via keystore.password
.
You can generate a keystore using the JDK's keytool:
./keytool -importcert -file some-cert.crt -keystore my.keystore -alias "<some-alias>"
Customization
For every client that is defined in your configuration the following graph of beans, indicated by the green color, will be created:
Regarding the other colors:
- yellow: will be created once and then shared across different clients (if needed)
- red: mandatory dependency
- grey: optional dependency
Every single bean in the graph can optionally be replaced by your own, custom version of it. Beans can only be overridden by name, not by type. As an example, the following code would add XML support to the example
client:
@Bean
@Qualifier("example")
public ClientHttpMessageConverters exampleHttpMessageConverters() {
return new ClientHttpMessageConverters(new Jaxb2RootElementHttpMessageConverter());
}
The following table shows all beans with their respective name (for the example
client) and type:
Bean Name | Bean Type | Configures by default |
---|---|---|
accessToken (no client prefix!) |
AccessTokens |
OAuth settings |
exampleHttpMessageConverters |
ClientHttpMessageConverters |
Text, JSON and JSON Stream |
exampleHttpClient |
HttpClient |
Interceptors and timeouts |
exampleAsyncClientHttpRequestFactory |
AsyncClientHttpRequestFactory and ClientHttpRequestFactory |
|
exampleRest |
Rest |
Base URL |
exampleRestTemplate |
RestTemplate |
Base URL |
exampleAsyncRestTemplate |
AsyncRestTemplate |
Base URL |
exampleAsyncListenableTaskExecutor |
AsyncListenableTaskExecutor |
ConcurrentTaskExecutor |
If you override a bean then all of its dependencies (see the graph), will not be registered, unless required by some other bean.
Getting Help
If you have questions, concerns, bug reports, etc., please file an issue in this repository's Issue Tracker.
Getting Involved/Contributing
To contribute, simply make a pull request and add a brief description (1-2 sentences) of your addition or change. For more details, check the contribution guidelines.