Cloud Native is a style of application development that encourages easy adoption of best practices in the areas of continuous delivery and value-driven development. A related discipline is that of building 12-factor Applications, in which development practices are aligned with delivery and operations goals — for instance, by using declarative programming and management and monitoring. Spring Cloud facilitates these styles of development in a number of specific ways. The starting point is a set of features to which all components in a distributed system need easy access.

Many of those features are covered by Spring Boot, on which Spring Cloud builds. Some more features are delivered by Spring Cloud as two libraries: Spring Cloud Context and Spring Cloud Commons. Spring Cloud Context provides utilities and special services for the ApplicationContext of a Spring Cloud application (bootstrap context, encryption, refresh scope, and environment endpoints). Spring Cloud Commons is a set of abstractions and common classes used in different Spring Cloud implementations (such Spring Cloud Consul).

If you get an exception due to "Illegal key size" and you use Sun’s JDK, you need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. See the following links for more information:

Extract the files into the JDK/jre/lib/security folder for whichever version of JRE/JDK x64/x86 you use.

Spring Cloud is released under the non-restrictive Apache 2.0 license. If you want to contribute to this section of the documentation or if you find an error, you can find the source code and issue trackers for the project at {docslink}[github].

1. Quick Start

This quick start walks through using SC LoadBalancer OkHttpClient integration, load-balanced OkHttpClient-based Retrofit clients, and load-balanced WebClient-based Retrofit clients.

1.1. OkHttpClient with Spring Cloud LoadBalancer

First, add the spring-cloud-square-okhttp dependency to your project:

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-square-okhttp</artifactId>
        <version>0.4.0-M1</version>
</dependency>

Then create a @LoadBalanced-annotated OkHttpClient.Builder bean:

@Configuration
class OkHttpClientConfig{
@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {
    return new OkHttpClient.Builder();
    }
}

Now you can use the serviceId or virtual hostname rather than an actual host:port in your requests — SC LoadBalancer resolves it by selecting one of the available service instances.

Request request = new Request.Builder()
                        .url("http://serviceId/hello").build();
Response response = builder.build().newCall(request).execute();

1.2. Retrofit with OkHttpClient and Spring Cloud LoadBalancer

First, add the spring-cloud-square-retrofit and spring-cloud-square-okhttp dependencies to your project:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-square-retrofit</artifactId>
        <version>0.4.0-M1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-square-okhttp</artifactId>
        <version>0.4.0-M1</version>
    </dependency>
</dependencies>

Use the @EnableRetrofitClients annotation to let us automatically instantiate and inject Retrofit clients for you. Then create a @LoadBalanced-annotated OkHttpClient.Builder bean to be used under the hood:

@Configuration
@EnableRetrofitClients
class OkHttpClientConfig {

@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {
    return new OkHttpClient.Builder();
    }
}

Create a Retrofit client and annotate it with @RetrofitClient, passing the serviceId of your service as argument (the annotation can also be used to pass a custom configuration that contains user-crated interceptors for the Retrofit client):

@RetrofitClient("serviceId")
interface HelloClient {
    @GET("/")
    Call<String> hello();
}

Make sure to use Retrofit method annotations, such as @GET("/"). You can now inject the Retrofit client and use it to run load-balanced calls (by using serviceId instead of actual host:port):

class AService {

    @Autowired
    HelloClient client;

    public String hello() throws IOException {
        return client.hello().execute().body();
    }
}

1.3. Retrofit with WebClient and Spring Cloud LoadBalancer

First, add the spring-cloud-square-retrofit and spring-boot-starter-webflux starter dependencies to your project:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-square-retrofit</artifactId>
        <version>0.4.0-M1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
</dependencies>

Use the @EnableRetrofitClients annotation to let us automatically instantiate and inject Retrofit clients for you. Then create a @LoadBalanced-annotated WebClient.Builder bean to be used under the hood:

@Configuration
@EnableRetrofitClients
class OkHttpClientConfig {

@Bean
@LoadBalanced
public WebClient.Builder okHttpClientBuilder() {
    return WebClient.builder();
    }
}

Create a Retrofit client and annotate it with @RetrofitClient, passing the serviceId of your service as argument:

@RetrofitClient("serviceId")
interface HelloClient {
    @GET("/")
    Mono<String> hello();
}

Make sure to use Retrofit method annotations, such as @GET("/"). You can now inject the Retrofit client and use it to run load-balanced calls (by using serviceId instead of actual host:port):

class AService {

    @Autowired
    HelloClient client;

    public String hello() throws IOException {
        return client.hello();
    }
}
As the currently available release is a milestone, you need to add the Spring Milestone repository link to your projects for all the examples presented in this blog entry:
<repositories>
    <repository>
        <id>spring-milestones</id>
        <url>https://repo.spring.io/milestone</url>
    </repository>
</repositories>

We recommend using dependency management for other Spring Cloud dependencies:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

Spring Cloud Square provides Spring Cloud LoadBalancer integration for OkHttpClient and Retrofit, as well as a WebClient-backed Retrofit clients.

2. OkHttpClient Spring Cloud LoadBalancer Integration

An interceptor is added to the OkHttpClient created by auto-configuration to resolve the scheme, host, and port from Spring Cloud LoadBalancer and rewrite the URL.

You can access this functionality by annotating OkHttpClient.Builder beans with @LoadBalanced:

@Configuration
class OkHttpClientConfig{
@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {
    return new OkHttpClient.Builder();
    }
}

Then you can use the serviceId or virtual hostname rather than an actual host:port in your requests — SC LoadBalancer resolves it by selecting one of the available service instances:

Request request = new Request.Builder()
                        .url("http://serviceId/hello").build();
Response response = builder.build().newCall(request).execute();
This integration supports all the LoadBalancer features. You can read more about them in the https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-loadbalancer[Spring Cloud Commons documentation].

You can also disable OkHttpClient load-balancing via properties, by setting the value of okhttp.loadbalancer.enabled to false.

3. Retrofit Integration

We provide Spring Boot and Spring Cloud LoadBalancer integration for Retrofit, which is a declarative HTTP client from Square.

To enable and instantiate Retrofit clients, use the @EnableRetrofitClients annotation over a Spring @Configuration class:

@EnableRetrofitClients(clients = TestClient.class, defaultConfiguration = LoggingRetrofitConfig.class)
@Configuration
class AppConfiguration{

}

It scans for interfaces that declare they are clients (through @RetrofitClient). You can further control the scope of the scan by specifying packages or client names in the annotation parameters. You can also use the defaultConfiguration parameter to specify the default config class for all your Retrofit clients.

You can create load-balanced Retrofit client beans by annotating a Retrofit interface with @RetrofitClient.

The next two listings show examples. The first one uses an OkHttpClient-specific Call interface in method signatures. You can use the second one with a WebClient-backed implementation.

@RetrofitClient("serviceId")
interface HelloClient {
    @GET("/")
    Call<String> hello();
}
@RetrofitClient("serviceId")
interface HelloClient {
    @GET("/")
    Mono<String> hello();
}

@RetrofitClient takes a value (alias name) argument, that also indicates the serviceId that should be used during load-balancing.

If you do not wish for the calls to be load-balanced, you should also use the url parameter, that allows you to set the full url, with host and port specified explicitly:

@RetrofitClient(name = "localapp", url = "http://localhost:8080")
    protected interface TestClient {

        @GET("/hello")
        Call<Hello> getHello();
}

Apart from setting the URL parameter, the @RetrofitClient annotation lets you specify a qualifier and pass a custom configuration class that you can use to provide or override OkHttp Interceptor beans:

@RetrofitClient(name = "localapp", configuration = CustomRetrofitConfig.class)
    protected interface TestClient {

        @GET("/hello")
        Call<Hello> getHello();
}

class CustomRetrofitConfig {

        @Bean
        public Interceptor interceptor1() {
            return chain -> {
                Request request = chain.request().newBuilder().addHeader(MYHEADER1, "myheader1value").build();
                return chain.proceed(request);
            };
        }
}
The configurations passed by the @RetrofitClient and @EnableRetrofitClients annotations behave similarly to the ones passed via @LoadBalancerClient and @LoadBalancerClients annotations. They are loaded into separate child contexts and should not be annotated with @Configuration.

3.1. Load-balanced Retrofit Clients

To use Spring Cloud LoadBalancer for instance selection and instance data retrieval, make sure you instantiate either a @LoadBalanced OkHttpClient.Builder (for a blocking implementation) or a @LoadBalanced Webclient.Builder (for a reactive implementation) bean in a @Configuration-annotated class in your application:

@Configuration
@EnableRetrofitClients
class OkHttpClientConfig {

@Bean
@LoadBalanced
public OkHttpClient.Builder okHttpClientBuilder() {
    return new OkHttpClient.Builder();
    }
}
@Configuration
@EnableRetrofitClients
class OkHttpClientConfig {

@Bean
@LoadBalanced
public WebClient.Builder okHttpClientBuilder() {
    return WebClient.builder();
    }
}

They are used under the hood to run load-balanced HTTP requests.

3.2. Retrofit Reactor support

When ReactorCallAdapterFactory is on the classpath (provided by retrofit2-reactor-adapter dependency), we also instantiate a bean of this type, by using available Scheduler (if present). You can disable this functionality in properties by setting the value of retrofit.reactor.enabled to false.