Skip to content

Type Refinement Traits

Juli Tera edited this page Apr 26, 2024 · 15 revisions

This wiki contains a mapping between Smithy Type refinement traits and generated Ruby code.

default Trait

Indicates that structure member has a default value.

@default(0)
integer ZeroValueInteger

structure MyOperationInput {
    zeroValueInteger: ZeroValueInteger = 0 // must be repeated and match the target.
}

See Smithy Documentation for more details.

addedDefault trait

Indicates that the @default trait was added to a structure member after initially publishing the member. This allows tooling to decide whether to ignore the @default trait if it will break backward compatibility in the tool.

See Smithy Documentation for more details.

required Trait

Marks a structure member as required, meaning a value for the member MUST be present and not set to null.

structure MyOperationInput {
    @required
    foo: FooString,
}

The generated code is:

# validators.rb
class MyOperationInput
  def self.validate!(input, context:)
    Hearth::Validator.validate_types!(input, Types::MyOperationInput, context: context)
    Hearth::Validator.validate_required!(input[:foo], context: "#{context}[:foo]") # ensures that this exists
    Hearth::Validator.validate_types!(input[:foo], ::String, context: "#{context}[:foo]")
  end
end

See Smithy Documentation for more details.

clientOptional trait

Treats a structure member as optional regardless of if the member is also marked with the required trait or default trait.

See Smithy Documentation for more details.

enumValue trait

Defines the value of an enum or intEnum. For enum shapes, a non-empty string value must be used. For intEnum shapes, an integer value must be used.

enum Enum {
    @enumValue("foo")
    FOO
}

intEnum IntEnum {
    @enumValue(1)
    FOO
}

Please note that - if an enum member doesn't have an explicit enumValue trait, an enumValue trait is implicitly added to the member with the trait value set to the member's name. See Smithy Documentation on enum values for more details.

error Trait

Indicates that a structure shape represents an error. Structures marked with this trait have a type definition, an error class, and a parser to populate the error structure.

@error("client")
structure NoSuchResource {
    @required
    resourceType: String,

    message: String,
}

The generated code is:

# types.rb
NoSuchResource = ::Struct.new(
  :resource_type,
  :message,
  keyword_init: true
) do
  include Hearth::Structure
end

# errors.rb
class NoSuchResource < ApiClientError
  def initialize(http_resp:, **kwargs)
    @data = Parsers::NoSuchResource.parse(http_resp)
    kwargs[:message] = @data.message if @data.respond_to?(:message)

    super(http_resp: http_resp, **kwargs)
  end

  # @return [Types::NoSuchResource]
  attr_reader :data
end

# parsers.rb
class NoSuchResource
  def self.parse(http_resp)
    data = Types::NoSuchResource.new
    data
  end
end

The Hearth error parser determines that the response has an error and delegates to the error class in errors.rb. Then the error’s class uses the parser in parsers.rb to populate a structure defined in types.rb.

Depending on the value passed to the @error trait, the error will inherit from ApiClientError or ApiServerError.

Read more on Errors and Smithy Documentation for trait details.

input Trait

Specializes a structure for use only as the input of a single operation. The @input trait is useful for modeling but is not used during SDK code generation.

@input
structure SomeOperationInput {
    name: String
}

See Smithy Documentation for more details.

output Trait

Specializes a structure for use only as the output of a single operation. The @output trait is useful for modeling but is not used during SDK code generation.

@output
structure SomeOperationOutput {
    name: String
}

See Smithy Documentation for more details.

sparse Trait

Indicates that lists and maps MAY contain null values. The protocol’s null values are represented by Ruby’s nil value.

@sparse
list SparseList {
    member: String
}

@sparse
map SparseMap {
    key: String,
    value: String
}

The generated code is:

# params.rb
class SparseList
  def self.build(params, context:)
    Hearth::Validator.validate_types!(params, ::Array, context: context)
    data = []
    params.each do |element|
      data << element
    end
    data
  end
end

class SparseMap
  def self.build(params, context:)
    Hearth::Validator.validate_types!(params, ::Hash, context: context)
    data = {}
    params.each do |key, value|
      data[key] = value
    end
    data
  end
end

For shapes without this trait, depending on the protocol, nil values are omitted when building or parsing the list element or map value. For example, check if unless element.nil? or unless value.nil? before populating the data structure.

See Smithy Documentation for more details.

mixin trait

A mixin is a shape that has the @mixin trait. Adding a mixin to a shape causes the members and traits of the mixin shape to be copied into the local shape.

@mixin
structure BaseUser {
    id: String
}

structure UserDetails with [BaseUser] {
    alias: String
    email: String
}

See Smithy Documentation for more details.

Clone this wiki locally