Smithy Language Specification

This document defines the ABNF grammar and syntax for defining models using the Smithy interface definition language (IDL) and the JSON abstract syntax tree (AST) that can be used to represent a model.

Smithy models MUST be encoded using UTF-8 and SHOULD use Unix style line endings.

Smithy IDL ABNF

The Smithy IDL is a series of statements separated by newlines.

idl =
    [statement *(1*br statement)]

statement =
    control_statement
  / metadata_statement
  / use_statement
  / namespace_statement
  / apply_statement
  / documentation_comment
  / shape_statement

Lexical notes

Whitespace is insignificant except for the following cases:

br =
    %x0A / %x0D.0A

Comments

Comments can occur at any place in the IDL between tokens where whitespace is insignificant. Comments in Smithy are defined using two forward slashes followed by any character. A newline terminates a comment.

line_comment =
    "//" *(start_comment *not_newline)

start_comment =
    %x09 / %x20-%x46 / %x48-10FFFF ; Any character other than "/" or newline

not_newline =
    %x09 / %x20-10FFFF             ; Any character but new line

Example:

// This is a comment
namespace com.foo // This is also a comment

// Another comment
string MyString

Control statement

Control statements apply metadata to a file. Control statements MUST be defined at the beginning of a Smithy file before any other statements.

control_statement =
    "$" text ":" node_value

Implementations SHOULD ignore unknown control statements.

Version statement

The version control statement is used to set the version of a Smithy model file. The value of a version statement MUST be a string. Only a single version statement can appear in a model file.

Example:

$version: "0.5.0"

Note

The Smithy specification is currently at version 0.5.0.

Metadata statement

The metadata statement is used to attach arbitrary metadata to a model.

metadata_statement =
    "metadata" metadata_key "=" metadata_value

metadata_key =
    text

metadata_value =
    node_value

Example:

metadata example.string1 = "hello there"
metadata example.string2 = 'hello there'
metadata example.bool1 = true
metadata example.bool2 = false
metadata example.number = 10
metadata example.array = [10, true, "hello"]
metadata example.object = {foo: "baz"}
metadata example.null = null

Top-level metadata key-value pair conflicts are resolved by merging metadata. Metadata statements MUST appear before any namespace statements or shapes are defined.

Namespace statement

The namespace statement is used to set the current namespace. Shapes can only be defined if a current namespace is defined. Only a single namespace can appear in an IDL model file.

namespace_statement =
    "namespace" namespace

Example:

namespace com.foo.baz

Use statement

A use statement is used to import shapes and traits into the current namespace so that they can be referred to using relative shape. A use statement MUST come after a namespace statement and before any shapes are defined in an IDL model file.

use_statement =
    "use" absolute_shape_id

The following example imports smithy.example#Foo and smithy.example#Baz so that they can be referred to by relative shape IDs:

namespace smithy.hello

use smithy.example#Foo
use smithy.example#Baz

map MyMap {
    // Resolves to smithy.example#Foo
    key: Foo,
    // Resolves to smithy.example#Baz
    value: Baz,
}

A use statement can import traits too. The following example imports the smithy.example#test and smithy.example#anotherTrait traits so that they can be applied using relative shape IDs:

namespace smithy.hello

use smithy.example#test
use smithy.example#anotherTrait

@test // <-- Resolves to smithy.example#test
string MyString

Important

  1. A shape cannot be defined in a file with the same name as one of the shapes imported with a use statement.
  2. Shapes IDs with members names cannot be imported with a use statement.

See Relative shape ID resolution for an in-depth description of how relative shape IDs are resolved in the IDL.

Shape statements

Shape statements are used to define shapes. Shapes can only be defined after a current namespace has been defined using a namespace statement.

shape_statement =
    [inline_traits br] shape_body

shape_body =
    service_statement
  / resource_statement
  / operation_statement
  / structure_statement
  / union_statement
  / list_statement
  / set_statement
  / map_statement
  / simple_shape

service_statement =
    "service" identifier node_object

resource_statement =
    "resource" identifier node_object

operation_statement =
    "operation" identifier node_object

structure_statement =
    "structure" structured_body

union_statement =
    "union" structured_body

structured_body =
    identifier "{" [structured_member *("," structured_member)] "}"

structured_member =
    member_traits identifier ":" shape_id

list_statement =
    "list" list_and_set_body

set_statement =
    "set" list_and_set_body

list_and_set_body =
    identifier "{" member_traits "member" ":" shape_id [","] "}"

map_statement =
    "map" identifier "{" map_body "}"

map_body =
    map_member "," map_member [","]

map_member =
    member_traits ("key" / "value") ":" shape_id

simple_shape =
    simple_shape_name identifier

simple_shape_name =
    "blob" / "boolean" / "document" / "string" / "byte" / "short"
  / "integer" / "long" / "float" / "double" / "bigInteger"
  / "bigDecimal" / "timestamp"

Apply statement

The apply statement is used to attach a trait to a shape outside of a shape's definition.

apply_statement =
    "apply" shape_id trait

The following example applies the deprecated trait trait to a shape named MyShape using a relative shape id.

apply MyShape @deprecated

Documentation comment

Documentation comments are a special kind of comment that provide documentation for shapes. A documentation comment is formed when three forward slashes ("///") appear as the first non-whitespace characters on a line.

documentation_comment =
    "///" *(not_newline)

Documentation comments are defined using CommonMark. The text after the forward slashes is considered the contents of the line. If the text starts with a space (" "), the leading space is removed from the content. Successive documentation comments are combined together using a newline ("\n") to form the documentation of a shape or trait definition.

Note

Documentation comments on shapes are just syntax sugar for applying the documentation trait.

The following Smithy IDL example,

namespace smithy.example

/// This is documentation about a shape.
///
/// - This is a list
/// - More of the list.
string MyString

/// This is documentation about a trait definition.
///   More docs here.
@trait
structure myTrait {}

is equivalent to the following JSON model:

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyString": {
            "type": "string",
            "traits": {
                "smithy.api#documentation": "This is documentation about a shape.\n\n- This is a list\n- More of the list."
            }
        },
        "smithy.example#myTrait": {
            "type": "structure",
            "traits": {
                "smithy.api#trait": {},
                "smithy.api#documentation": "This is documentation about a trait definition.\n  More docs here."
            }
        }
    }
}

Documentation comments MUST appear immediately before a shape, and they MUST appear before any traits applied to the shape.

The following example is valid because the documentation comment comes before the traits applied to a shape:

/// A deprecated string.
@deprecated
string MyString

Documentation comments can be applied to members of a shape.

// Documentation about the structure.
structure Example {
    /// Documentation about the member.
    @sensitive
    foo: String,
}

Documentation comments MUST NOT be applied to anything other than shapes. The following documentation comments are all invalid.

/// Invalid (cannot apply to control statements)
$version: "0.5.0"

/// Invalid (cannot apply to namespaces)
namespace smithy.example

/// Invalid (cannot apply to metadata)
metadata foo = "baz"

@deprecated
/// Invalid (comes after the @deprecated trait)
structure Example {
    /// Invalid (cannot apply docs to '}')
}

/// Invalid (nothing comes after the comment)

Trait values

Trait values are traits attached to shapes. Trait values can only appear immediately before a shape or member definition.

inline_traits =
    [trait *trait]

trait =
    "@" shape_id ["(" trait_body_value ")"]

trait_body_value =
    trait_structure / node_value

trait_structure =
    trait_structure_kvp *("," trait_structure_kvp)

trait_structure_kvp =
    text ":" node_value

member_traits =
    [inline_traits]

The following example applies various traits to a structure shape and its members.

@documentation("An animal in the animal kingdom")
structure Animal {
    @required
    name: smithy.api#String,

    @deprecated
    @deprecationReason("Use name instead")
    subject: smithy.api#String,

    @length(min: 0)
    age: smithy.api#Integer,
}

String values

String values are utilized in various contexts. String values can be unquoted if they adhere to the unquoted_text production.

Smithy strings are considered raw strings, meaning they do not support any form of escapes other than to escape a closing quote (using \" or \') or to escape an escape (using \\).

text =
    unquoted_text / quoted_text / text_block

unquoted_text =
    (ALPHA / "_") *(ALPHA / DIGIT / "_" / "$" / "." / "#")

escaped_char =
    escape (escape / "'" / DQUOTE / "b" / "f" / "n" / "r" / "t" / "/" / unicode_escape)

unicode_escape =
    "u" hex hex hex hex

hex =
     DIGIT / %x41-46 / %x61-66

quoted_text =
    DQUOTE *quoted_char DQUOTE

quoted_char =
    %x20-21
  / %x23-5B
  / %x5D-10FFFF
  / escaped_char
  / preserved_double

preserved_double =
    escape (%x20-21 / %x23-5B / %x5D-10FFFF)

escape =
    %x5C ; backslash

text_block =
    DQUOTE DQUOTE DQUOTE br quoted_char DQUOTE DQUOTE DQUOTE

New lines in strings are normalized from CR (u000D) and CRLF (u000Du000A) to LF (u000A). This ensures that strings defined in a Smithy model are equivalent across platforms. If a literal \r is desired, it can be added a string value using the Unicode escape \u000d.

Unquoted strings

Unquoted strings that appear in the IDL as part of a trait value or metadata value are treated as shape IDs. Strings MUST be quoted if a value is not intended to be converted into a resolved shape ID.

See Syntactic shape IDs in the IDL for more information.

Text blocks

A text block is a string literal that can span multiple lines and automatically removes any incidental whitespace. A text block is opened with three double quotes ("""), followed by a newline, zero or more content characters, and closed with three double quotes.

Smithy text blocks are heavily based on text blocks defined in JEP 355

Text blocks differentiate incidental whitespace from significant whitespace. Smithy will re-indent the content of a text block by removing all incidental whitespace.

@documentation("""
    <div>
        <p>Hello!</p>
    </div>
    """)

The four leading spaces in the above text block are considered insignificant because they are common across all lines. Because the closing delimiter appears on its own line, a trailing new line is added to the result. The content of the text block is re-indented to remove the insignificant whitespace, making it equivalent to the following:

@documentation("<div>\n    <p>Hello!</p>\n</div>\n")

The closing delimiter can be placed on the same line as content if no new line is desired at the end of the result. The above example could be rewritten to not including a trailing new line:

@documentation("""
    <div>
        <p>Hello!</p>
    </div>""")

This example is equivalent to the following:

@documentation("<div>\n    <p>Hello!</p>\n</div>")

The following text blocks are ill-formed:

"""foo"""  // missing new line following open delimiter
""" """    // missing new line following open delimiter
"""
"          // missing closing delimiter
Incidental white space removal

Smithy will re-indent the content of a text block by removing all incidental whitespace using the following algorithm:

  1. Split the content of the text block at every LF, producing a list of lines. The opening LF of the text block is not considered.

    Given the following example ("." is used to represent spaces),

    @documentation("""
    ....Foo
    ........Baz
    
    ..
    ....Bar
    ....""")
    

    the following lines are produced:

    ["    Foo", "        Baz", "", "  ", "    Bar", "    "]
    
  2. Compute the common whitespace prefix by iterating over each line, counting the number of leading spaces (" ") and taking the minimum count. Except for the last line of content, lines that are empty or consist wholly of whitespace are not considered. If the last line of content (that is, the line that contains the closing delimiter) appears on its own line, then that line's leading whitespace is considered when determining the common whitespace prefix, allowing the closing delimiter to determine the amount of indentation to remove.

    Using the previous example, the common whitespace prefix is four spaces. The empty third line and the blank fourth lines are not considered when computing the common whitespace. The following uses "." to represent the common whitespace prefix:

    @documentation("""
    ....Foo
    ....    Baz
    
    ....
    ....Bar
    ....""")
    
  3. Remove the common white space prefix from each line.

    This step produces the following values from the previous example:

    ["Foo", "    Baz", "", "", "Bar", ""]
    
  4. Remove any trailing spaces from each line.

  5. Concatenate each line together, separated by LF.

    This step produces the following result ("|" is used to represent the left margin):

    |Foo
    |    Baz
    |
    |
    |Bar
    |
    
Significant trailing line

The last line of text block content is used when determining the common whitespace prefix.

Consider the following example:

@documentation("""
    Foo
        Baz
    Bar
""")

Because the closing delimiter is at the margin and left of the rest of the content, the common whitespace prefix is 0 characters, resulting in the following equivalent string:

@documentation("    Foo\n        Baz\n    Bar\n")

If the closing delimiter is moved to the right of the content, then it has no bearing on the common whitespace prefix. The common whitespace prefix in the following example is visualized using "." to represent spaces:

@documentation("""
....Foo
....    Baz
....Bar
        """)

Because lines are trimmed when they are added to the result, the above example is equivalent to the following:

@documentation("Foo\n    Baz\nBar\n")
Escapes in text blocks

Text blocks support all of the string escape characters of other strings. The use of three double quotes allows unescaped double quotes (") to appear in text blocks. The following text block is interpreted as "hello!":

"""
"hello!"
"""

Three quotes can appear in a text block without being treated as the closing delimiter as long as one of the quotes are escaped. The following text block is interpreted as foo """\nbaz:

"""
foo \"""
baz"""

String escapes are interpreted after incidental whitespace is removed from a text block. The following example uses "." to denote spaces:

"""
..<div>
....<p>Hi\\n....bar</p>
..</div>
.."""

Because string escapes are expanded after incidental whitespace is removed, it is interpreted as:

<div>
..<p>Hi
....bar</p>
</div>

New lines in the text block can be escaped. This allows for long, single-line strings to be broken into multiple lines in the IDL. The following example is interpreted as Foo Baz Bam:

"""
Foo \
Baz \
Bam"""

Escaped new lines can be intermixed with unescaped newlines. The following example is interpreted as Foo\nBaz Bam:

"""
Foo
Baz \
Bam"""

String escape characters

The Smithy IDL supports escape sequences only within quoted strings. Smithy supports all of the same escape sequences as JSON plus escaping of single quotes.

The following sequences are allowed:

Unicode code point Smithy escape Meaning
U+0022 \" double quote
U+0027 \' single quote
U+005C \\ backslash
U+002F \/ forward slash
U+0008 \b backspace BS
U+000C \f form feed FF
U+000A \n line feed LF
U+000D \r carriage return CR
U+0009 \t horizontal tab HT
U+HHHH \uHHHH 4-digit hexadecimal Unicode code point
nothing \\r\n, \\r, \\n escaped new line expands to nothing

Any other sequence following a backslash is an error.

Node values

Node values are analogous to JSON values. Node values are used to define metadata and trait values.

Smithy's node values have many advantages over JSON: comments, unquoted keys, unquoted strings, single quoted strings, long strings, and trailing commas.

node_value =
    text / number / node_array / node_object

node_array =
    "[" [node_value *("," node_value)] (( "," "]" ) / "]" )

node_object =
    "{" [node_object_kvp *("," node_object_kvp)] (( "," "}" ) / "}" )

node_object_kvp =
    text ":" node_value

number =
    [minus] int [frac] [exp]

decimal_point =
    %x2E ; .

digit1_9 =
    %x31-39 ; 1-9

e =
    %x65 / %x45 ; e E

exp =
    e [minus / plus] 1*DIGIT

frac =
    decimal_point 1*DIGIT

int =
    zero / (digit1_9 *DIGIT)

minus =
    %x2D ; -

plus =
    %x2B ; +

zero =
    %x30 ; 0

The following example defines a string metadata key:

metadata foo = "baz"

The following example defines an integer metadata key:

metadata foo = 100

The following example defines an array metadata key:

metadata foo = ["hello", 123, true, [false]]

The following example defines a complex object metadata key:

metadata foo = {
    hello: 123,
    'foo': "456",
    testing: """
        Hello!
        """,
    an_array: [10.5],
    nested-object: {
        hello-there$: true
    }, // <-- Trailing comma
}

Shape ID ABNF

Shape IDs adhere to the following ABNF.

Lexical note

Whitespace is significant in shape IDs.

identifier =
    (ALPHA / "_") *(ALPHA / DIGIT / "_")

namespace =
    identifier *("." identifier)

shape_id =
    absolute_shape_id / relative_shape_id

absolute_shape_id =
    namespace "#" relative_shape_id

relative_shape_id =
    identifier ["$" identifier]

LOALPHA =
    %x61-7A ; a-z

JSON AST

Smithy models written using the Smithy IDL have an isomorphic JSON abstract syntax tree (AST) representation that can be used to more easily integrate Smithy into languages and tools that do not have a Smithy IDL parser.

  • Smithy JSON models can be merged together with other JSON models or other Smithy IDL models using the rules defined in Merging models.
  • Unless specified otherwise, the same constraints and logic is used to load JSON models that is used to load Smithy IDL models.
  • All shape IDs in the JSON AST MUST be absolute shape IDs that contain a namespace. One of the main drivers of the simplicity of the the JSON AST over the Smithy IDL is that relative and forward references never need to be resolved.

Top level properties

Smithy JSON models are objects that can contain the following top-level properties:

Property Type Description
smithy string Required. Defines the version of the Smithy specification (e.g., "0.5.0").
metadata object Defines all of the metadata about the model using a JSON object. Each key is the metadata key to set, and each value is the metadata value to assign to the key.
shapes Map<shape ID, AST shape> A map of absolute shape IDs to shape definitions.

AST shapes

AST shapes are defined using objects that always contain a type property to define the shape type or apply.

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyString": {
            "type": "string"
        }
    }
}

All entries in the shapes map can contain a traits property that defines the traits attached to the shape. traits is a map of where each key is the absolute shape IDs of a trait definition and each value is the value to assign to the trait.

{
    "traits": {
        "smithy.example#documentation": "Hi!",
        "smithy.example#tags": [
            "a",
            "b"
        ]
    }
}

The following example defines a string shape with a documentation trait.

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyString": {
            "type": "string",
            "traits": {
                "smithy.api#documentation": "My documentation string"
            }
        }
    }
}

Simple shapes

Simple shapes are defined as an object. The following example defines a shape for each simple type:

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#Blob": {
            "type": "blob"
        },
        "smithy.example#Boolean": {
            "type": "boolean"
        },
        "smithy.example#Document": {
            "type": "document"
        },
        "smithy.example#String": {
            "type": "string"
        },
        "smithy.example#Byte": {
            "type": "byte"
        },
        "smithy.example#Short": {
            "type": "short"
        },
        "smithy.example#Integer": {
            "type": "integer"
        },
        "smithy.example#Long": {
            "type": "long"
        },
        "smithy.example#Float": {
            "type": "float"
        },
        "smithy.example#Double": {
            "type": "double"
        },
        "smithy.example#BigInteger": {
            "type": "bigInteger"
        },
        "smithy.example#BigDecimal": {
            "type": "bigDecimal"
        },
        "smithy.example#Timestamp": {
            "type": "timestamp"
        }
    }
}

List and set shapes

list and set shapes have a required member property that is an AST member.

The following example defines a list with a string member:

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyList": {
            "type": "list",
            "member": {
                "target": "smithy.api#String"
            }
        }
    }
}

The following example defines a set with a string member:

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MySet": {
            "type": "set",
            "member": {
                "target": "smithy.api#String"
            }
        }
    }
}

AST member

An AST member definition defines a member of a shape. It is a special kind of AST shape reference that also contains an optional traits property that defines traits attached to the member. Each key in the traits property is the absolute shape ID of the trait to apply, and each value is the value to assign to the trait.

{
    "target": "smithy.example#MyShape",
    "traits": {
        "smithy.example#documentation": "Hi!"
    }
}

The following example defines a list shape and its member.

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyList": {
            "type": "list",
            "member": {
                "target": "smithy.api#String",
                "traits": {
                    "smithy.api#documentation": "Member documentation"
                }
            }
        }
    }
}

AST shape reference

An AST shape reference is an object with a single property, target that maps to an absolute shape ID.

{
    "target": "smithy.example#MyShape"
}

The following example defines a shape reference inside of the operations list of a service shape.

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#Service": {
            "type": "service",
            "operations": [
                {
                    "target": "smithy.example#Operation"
                }
            ]
        },
        "smithy.example#Operation": {
            "type": "operation"
        }
    }
}

Map shape

A map shape has a required key and value AST member. The shape referenced by the key member MUST target a string shape.

The following example defines a map of strings to numbers:

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#IntegerMap": {
            "type": "map",
            "key": {
                "target": "smithy.api#String"
            },
            "value": {
                "target": "smithy.api#Integer"
            }
        }
    }
}

Structure and union shapes

Structure and union shapes are defined with a members property that contains a map of member names to AST member definitions. A union shape requires at least one member, and a structure shape MAY omit the members property entirely if the structure contains no members.

Structure and union member names MUST be case-insensitively unique across the entire set of members. Each member name MUST adhere to the identifier ABNF grammar.

The following example defines a structure with one required and one optional member:

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyStructure": {
            "type": "structure",
            "members": {
                "stringMember": {
                    "target": "smithy.api#String",
                    "traits": {
                        "smithy.api#required": true
                    }
                },
                "numberMember": {
                    "target": "smithy.api#Integer"
                }
            }
        }
    }
}

The following example defines a union:

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyUnion": {
            "type": "union",
            "members": {
                "a": {
                    "target": "smithy.api#String"
                },
                "b": {
                    "target": "smithy.api#Integer"
                }
            }
        }
    }
}

Service shape

Service shapes are defined using an object. Service shapes defined in JSON support the same properties as the Smithy IDL.

Property Type Description
type string service
version string Required. Defines the version of the service. The version can be provided in any format (e.g., 2017-02-11, 2.0, etc).
operations [AST shape reference] Binds a list of operations to the service. Each reference MUST target an operation.
resources [AST shape reference] Binds a list of resources to the service. Each reference MUST target a resource.
traits Map<shape ID, trait value> Traits to apply to the service
{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyService": {
            "type": "service",
            "version": "2017-02-11",
            "operations": [
                {
                    "target": "smithy.example#GetServerTime"
                }
            ],
            "resources": [
                {
                    "target": "smithy.example#SomeResource"
                }
            ]
        }
    }
}

Resource shape

Resource shapes are defined using an object. Resource shapes defined in JSON support the same properties as the Smithy IDL.

Property Type Description
type string service
identifiers Map<String, AST shape reference> Defines identifier names and shape IDs used to identify the resource.
create AST shape reference Defines the lifecycle operation used to create a resource using one or more identifiers created by the service.
put AST shape reference Defines an idempotent lifecycle operation used to create a resource using identifiers provided by the client.
read AST shape reference Defines the lifecycle operation used to retrieve the resource.
update AST shape reference Defines the lifecycle operation used to update the resource.
delete AST shape reference Defines the lifecycle operation used to delete the resource.
list AST shape reference Defines the lifecycle operation used to list resources of this type.
operations [AST shape reference] Binds a list of non-lifecycle instance operations to the resource. Each reference MUST target an operation.
collectionOperations [AST shape reference] Binds a list of non-lifecycle collection operations to the resource. Each reference MUST target an operation.
resources [AST shape reference] Binds a list of resources to this resource as a child resource, forming a containment relationship. The resources MUST NOT have a cyclical containment hierarchy, and a resource can not be bound more than once in the entire closure of a resource or service. Each reference MUST target a resource.
traits Map<shape ID, trait value> Traits to apply to the resource.
{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#Thing": {
            "type": "resource",
            "identifiers": {
                "forecastId": {
                    "target": "smithy.api#String"
                },
            },
            "create": {
                "target": "smithy.example#CreateThing"
            },
            "read": {
                "target": "smithy.example#GetThing"
            },
            "update": {
                "target": "smithy.example#Updatething"
            },
            "delete": {
                "target": "smithy.example#DeleteThing"
            },
            "list": {
                "target": "smithy.example#ListThings"
            },
            "operations": [
                {
                    "target": "smithy.example#SomeInstanceOperation"
                }
            ],
            "collectionOperations": [
                {
                    "target": "smithy.example#SomeCollectionOperation"
                }
            ],
            "resources": [
                {
                    "target": "smithy.example#SomeResource"
                }
            ]
        }
    }
}

Operation shape

Operation shapes are defined using an object with the following properties:

Property Type Description
type string operation
input AST shape reference Defines the optional input structure of the operation. The input of an operation MUST resolve to a structure.
output AST shape reference Defines the optional output structure of the operation. The output of an operation MUST resolve to a structure.
errors [AST shape reference] Defines the list of errors that MAY be encountered when invoking the operation. Each reference MUST resolve to a structure shape that is marked with the error trait trait.
traits Map<shape ID, trait value> Traits to apply to the operation.

The following example defines an operation, its input, output, and errors:

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#MyOperation": {
            "type": "operation",
            "input": {
                "target": "smithy.example#MyOperationInput"
            },
            "output": {
                "target": "smithy.example#MyOperationOutput"
            },
            "errors": [
                {
                    "target": "smithy.example#BadRequestError"
                },
                {
                    "target": "smithy.example#NotFoundError"
                }
            ]
        },
        "smithy.example#MyOperationInput": {
            "type": "structure"
        },
        "smithy.example#MyOperationOutput": {
            "type": "structure"
        },
        "smithy.example#BadRequestError": {
            "type": "structure",
            "traits": {
                "smithy.api#error": "client"
            }
        },
        "smithy.example#NotFoundError": {
            "type": "structure",
            "traits": {
                "smithy.api#error": "client"
            }
        }
    }
}

AST apply type

A type of apply can be used to apply traits to shapes outside of a shape's definition. The apply type does not actually define a shape for the shape ID; the shape ID MUST reference a shape or member of a shape. The apply type allows only the traits property.

{
    "smithy": "0.5.0",
    "shapes": {
        "smithy.example#Struct": {
            "type": "structure",
            "members": {
                "foo": {
                    "target": "smithy.api#String"
                }
            }
        },
        "smithy.example#Struct$foo": {
            "type": "apply",
            "traits": {
                "smithy.api#documentation": "My documentation string"
            }
        }
    }
}
Selectors →