1**Design:** Convention, **Status:** [Accepted](README.md) 2 3## Client Configuration 4 5This page describes the structure and conventions used for client configuration objects. Client configuration objects are any objects used to configure an AWS client builder. 6 7#### Example 8 9This section walks through an example configuration class structure and describes each of its components at a high level. 10 11```Java 12/** 13 * Configuration Description // (1) 14 */ 15@Immutable 16@ThreadSafe // (2) 17public final class SdkConfiguration // (3) 18 implements ToCopyableBuilder<SdkConfiguration.Builder, SdkConfiguration> { // (4) 19 private final String option; // (5) 20 21 /** 22 * @see #builder() // (6) 23 */ 24 private SdkClientConfiguration(DefaultSdkConfigurationBuilder builder) { 25 this.option = builder.option; 26 } 27 28 public static Builder builder() { 29 return new DefaultSdkConfigurationBuilder(); 30 } 31 32 /** 33 * @see #Builder#option(String) // (7) 34 */ 35 public String option() { 36 return this.option; 37 } 38 39 @Override 40 public ClientHttpConfiguration.Builder toBuilder() { 41 return builder().option(option); 42 } 43 44 @NotThreadSafe 45 public interface Builder extends CopyableBuilder<Builder, SdkConfiguration> { // (8) 46 /** 47 * Configuration Option Description // (9) 48 */ 49 Builder option(String option); 50 } 51 52 private static final class DefaultSdkConfigurationBuilder implements Builder { // (10) 53 private String option; 54 55 @Override 56 public Builder option(String option) { // (11) 57 this.option = option; 58 return this; 59 } 60 61 public void setOption(String option) { // (12) 62 this.option = option; 63 } 64 65 @Override 66 public SdkConfiguration build() { 67 return new SdkConfiguration(this); 68 } 69 } 70} 71``` 72 731. A detailed description should be given of what types of options the user might find in this object. 742. Configuration objects should be `@Immutable`, and therefore `@ThreadSafe`. 753. Configuration classes should be defined as `final` to prevent extension. 764. Configuration classes should extend `ToCopyableBuilder` to ensure they can be converted back to a builder object. 775. All configuration fields should be defined as `private final` to prevent reassignment. 786. Configuration constructors should be `private` to enforce creation by the `Builder` and refer curious eyes to the `builder()` method for creating the object. 797. One "get" method should be created for each configuration field. This method's name should exactly match the name of the field it is retrieving. 808. Each builder should have its own interface. This allows hiding certain public methods from auto-complete (see below). 819. A detailed description of each option should be given, including what it does, and **why** a user could want to change its default value. 8210. A `private static final` implementation of the `Builder` interface should be created that is not exposed outside of the scope of the configuration class. 8311. One "set" method should be created for each option to mutate the value in this builder. This method's name should exactly match the name of the field it is setting. 8412. Each option should have a bean-style setter to allow configuring the object reflectively using `Inspector`-based frameworks, like spring XML. 85 86#### Configuration Fields 87 88This section details the semantics of configuration fields. 89 901. Configuration fields must be **immutable**. 91 1. Fields must be marked as `final`. 92 2. Mutable types, like `List` and `Set` should be wrapped in a type that prevents their modification (eg. `Collections.unmodifiableList`) when referenced through the "get" method. 93 3. Mutable types, like `List` and `Set` should be copied in the "set" method to prevent their modification by mutating the original object. 942. Configuration fields must be **reference types**. Primitive types like `boolean` or `int` should not be used because they can not convey the absence of configuration. 953. Configuration field names should **not start with a verb** (eg. `config.enableRedirect()` should instead be `config.redirectEnabled()`). This is to avoid confusing their "get" methods for a mutating action. 96 97Special notes for collection types, like `List`, `Set`, and `Map`: 98 991. Collection type field names must be plural. 1002. There should be two methods provided to modify the collection. 101 - method with plural field name which permits adding a collection. It should override any values currently configured in the builder. 102 - method that permits adding one item to the collection. 103 - If the collection is a list, the method name should use `add` prefix, eg: `addApiName` 104 - If the collection is a map, the method name should use `put` prefix, eg: `putHeader` 105 106```Java 107public interface Builder { 108 109 /** 110 * Sets options. 111 * 112 * <p> 113 * This overrides any option values already configured in the builder. 114 */ 115 Builder options(List<String> options); 116 117 /** 118 * Add a single option to the collection. 119 */ 120 Builder addOption(String option); 121 122 /** 123 * Sets headers to be set on the HTTP request. 124 * 125 * <p> 126 * This overrides any header values already configured in the builder. 127 */ 128 Builder headers(Map<String, String> headers); 129 130 /** 131 * Add a single header to be set on the HTTP request. 132 * 133 * <p> 134 * This overrides any values already configured with this header name in the builder. 135 */ 136 Builder putHeader(String key, String value); 137} 138``` 139