Skip to content
Matt Muller edited this page May 5, 2022 · 10 revisions

The config class is an immutable struct that contains the options that will be used by the Client. It can resolve default value chains and validates provided values against expected types. Config classes are 1:1 with a Smithy service shape.

Usage

A Config object should be created using .new and passed any values. Config has default values (can be sourced from multiple locations) that are automatically applied. Config will also validate that provided values are of expected types; For example, :endpoint is validated to be a String. Once constructed, the Config object is expected to be passed to the Client for usage.

config = WhiteLabel::Config.new(
  endpoint: 'https://my.custom.endpoint.com',
  validate_input: false
)

client1 = Service::Client.new(config)
client2 = Service::Client.new(config)

Note that the Config object is passed to the Client as a reference. Config is immutable, but it may contain "refreshed" values such as credentials, and is applied to all Clients that use this Config instance.

Example Config structure

In this example, a Config structure consists of various options used by default middleware. A validate! method that contains type validations is defined, and is called by the Hearth::Configuration module on initialize. A self.defaults method returns a hash of defaults for each key, where the value is a chain (Array) of potential values, where each value is static or responds to call.

module WhiteLabel
  Config = ::Struct.new(
    :adaptive_retry_wait_to_fill,
    :disable_host_prefix,
    :endpoint,
    :http_wire_trace,
    :log_level,
    :logger,
    :max_attempts,
    :retry_mode,
    :stub_responses,
    :validate_input,
    keyword_init: true
  ) do
    include Hearth::Configuration

    private

    def validate!
      Hearth::Validator.validate!(adaptive_retry_wait_to_fill, TrueClass, FalseClass, context: 'options[:adaptive_retry_wait_to_fill]')
      Hearth::Validator.validate!(disable_host_prefix, TrueClass, FalseClass, context: 'options[:disable_host_prefix]')
      Hearth::Validator.validate!(endpoint, String, context: 'options[:endpoint]')
      Hearth::Validator.validate!(http_wire_trace, TrueClass, FalseClass, context: 'options[:http_wire_trace]')
      Hearth::Validator.validate!(log_level, Symbol, context: 'options[:log_level]')
      Hearth::Validator.validate!(logger, Logger, context: 'options[:logger]')
      Hearth::Validator.validate!(max_attempts, Integer, context: 'options[:max_attempts]')
      Hearth::Validator.validate!(retry_mode, String, context: 'options[:retry_mode]')
      Hearth::Validator.validate!(stub_responses, TrueClass, FalseClass, context: 'options[:stub_responses]')
      Hearth::Validator.validate!(validate_input, TrueClass, FalseClass, context: 'options[:validate_input]')
    end

    def self.defaults
      @defaults ||= {
        adaptive_retry_wait_to_fill: [true],
        disable_host_prefix: [false],
        endpoint: [proc { |cfg| cfg[:stub_responses] ? 'http://localhost' : nil } ],
        http_wire_trace: [false],
        log_level: [:info],
        logger: [proc { |cfg| Logger.new($stdout, level: cfg[:log_level]) } ],
        max_attempts: [3],
        retry_mode: ['standard'],
        stub_responses: [false],
        validate_input: [true]
      }.freeze
    end
  end
end