Website | Source | Docs (2.0)
Smithy models consist of shapes and traits. Shapes are instances of types. Traits are used to add more information to shapes that might be useful for clients, servers, or documentation.
Smithy supports the following types:
Type | Description |
---|---|
blob | Uninterpreted binary data |
boolean | Boolean value type |
string | UTF-8 encoded string |
byte | 8-bit signed integer ranging from -128 to 127 (inclusive) |
short | 16-bit signed integer ranging from -32,768 to 32,767 (inclusive) |
integer | 32-bit signed integer ranging from -2^31 to (2^31)-1 (inclusive) |
long | 64-bit signed integer ranging from -2^63 to (2^63)-1 (inclusive) |
float | Single precision IEEE-754 floating point number |
double | Double precision IEEE-754 floating point number |
bigInteger | Arbitrarily large signed integer |
bigDecimal | Arbitrary precision signed decimal number |
timestamp | An instant in time with no UTC offset or timezone. |
document | An untyped JSON-like value. |
List | Homogeneous collection of values |
Map | Map data structure that maps string keys to homogeneous values |
Structure | Fixed set of named heterogeneous members |
Union | Tagged union data structure that can take on several different, but fixed, types |
Service | Entry point of an API that aggregates resources and operations together |
Operation | Represents the input, output and possible errors of an API operation |
Resource | An entity with an identity, set of operations, and child resources |
A resource is contained within a service or another resource. Resources have identifiers, operations, and any number of child resources.
model/weather.smithy
$version: "2"
namespace example.weather
/// Provides weather forecasts.
service Weather {
version: "2006-03-01"
resources: [
City
]
}
resource City {
identifiers: { cityId: CityId }
read: GetCity
list: ListCities
}
// "pattern" is a trait.
@pattern("^[A-Za-z0-9 ]+$")
string CityId
Because the Weather service contains many cities, the City resource defines an identifier. Identifiers are used to refer to a specific resource within a service. The "identifiers" property is a mapping of identifier names to the shape to use for that identifier. If the input structure of an operation uses the same names and targeted shapes as the identifiers property of the resource, the structure is automatically configured to work with the resource so that input members of the operation are used to provide the identity of the resource.
Each City has a single Forecast. This can be defined by adding the Forecast resource to the resources property of the City resource.
resource City {
identifiers: { cityId: CityId }
read: GetCity
list: ListCities
resources: [
Forecast
]
}
resource Forecast {
identifiers: { cityId: CityId }
read: GetForecast
}
Child resources must define the exact same identifiers property of their parent, but they are allowed to add any number of additional identifiers if needed. Because there is only one forecast per city, no additional identifiers were added to the identifiers property that isn't present on the City resource.
The state of a resource is represented through its properties. City contains coordinates, and Forecast has a chance of rain represented as a float. Input and output members of resource operations map to resource properties or identifiers to perform updates on or examine the state of a resource.
model/weather.smithy
resource City {
identifiers: { cityId: CityId }
properties: { coordinates: CityCoordinates }
read: GetCity
list: ListCities
resources: [
Forecast
]
}
structure CityCoordinates {
@required
latitude: Float
@required
longitude: Float
}
structure GetCityOutput for City {
$coordinates
}
resource Forecast {
identifiers: { cityId: CityId }
properties: { chanceOfRain: Float }
read: GetForecast
}
structure GetForecastOutput for Forecast {
$chanceOfRain
}
The put, create, read, update, delete, and list properties of a resource are used to define the lifecycle operations of a resource. Lifecycle operations are the canonical methods used to read and transition the state of a resource using well-defined semantics. Defining lifecycle operations helps automated tooling reason about your API.
Let's define the operation used to "read" a City.
model/weather.smithy
@readonly
operation GetCity {
input := for City {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
$cityId
}
output := for City {
// "required" is used on output to indicate if the service
// will always provide a value for the member.
// "notProperty" indicates that top-level input member "name"
// is not bound to any resource property.
@required
@notProperty
name: String
@required
$coordinates
}
errors: [
NoSuchResource
]
}
// "error" is a trait that is used to specialize
// a structure as an error.
@error("client")
structure NoSuchResource {
@required
resourceType: String
}
And define the operation used to "read" a Forecast.
model/weather.smithy
@readonly
operation GetForecast {
// "cityId" provides the only identifier for the resource since
// a Forecast doesn't have its own.
input := for Forecast {
@required
$cityId
}
output := for Forecast {
$chanceOfRain
}
}
Review
Last modified 18 May 2025