6. Protocol traits#

Serialization and protocol traits define how data is transferred over the wire.

6.1. protocolDefinition trait#

Summary
A meta-trait that marks a trait as a protocol definition trait. Traits that are marked with this trait are applied to service shapes to define the protocols supported by a service. A client MUST understand at least one of the protocols in order to successfully communicate with the service.
Trait selector
[trait|trait]
Value type

An object with the following properties:

Property Type Description
traits [Shape ID] List of shape IDs that protocol implementations MUST understand in order to successfully use the protocol. Each shape MUST exist and MUST be a trait. Code generators SHOULD ensure that they support each listed trait.
noInlineDocumentSupport boolean If set to true, indicates that this protocol does not support document type shapes. A service that uses such a protocol MUST NOT contain any document shapes in their service closure.

Smithy is protocol agnostic, which means it focuses on the interfaces and abstractions that are provided to end-users rather than how the data is sent over the wire. In Smithy, a protocol is a named set of rules that defines the syntax and semantics of how a client and server communicate. This includes the application layer protocol of a service (for example, HTTP) and the serialization formats used in messages (for example, JSON). Traits MAY be used to influence how messages are serialized (for example, jsonName trait and xmlAttribute trait).

The following example defines a service that supports both the hypothetical jsonExample and xmlExample protocols.

/// An example JSON protocol.
@protocolDefinition
@trait(selector: "service")
structure jsonExample {}

/// An example XML protocol.
@protocolDefinition
@trait(selector: "service")
structure xmlExample {}

@jsonExample
@xmlExample
service WeatherService {
    version: "2017-02-11",
}

Because protocol definitions are just specialized shapes, they can also support configuration settings.

@protocolDefinition
@trait(selector: "service")
structure configurableExample {
    @required
    version: String
}

@configurableExample(version: "1.0")
service WeatherService {
    version: "2017-02-11",
}

6.2. jsonName trait#

Summary
Allows a serialized object property name in a JSON document to differ from a structure or union member name used in the model.
Trait selector

:is(structure, union) > member

Any structure or union member

Value type
string

Given the following structure definition,

structure MyStructure {
    @jsonName("Foo")
    foo: String,

    bar: String,
}

and the following values provided for MyStructure,

"foo" = "abc"
"bar" = "def"

the JSON representation of the value would be serialized with the following document:

{
    "Foo": "abc",
    "bar": "def"
}

Note

No two members of the same structure or union can use the same case-sensitive @jsonName.

6.3. mediaType trait#

Summary
Describes the contents of a blob or string shape using a design-time media type as defined by RFC 6838 (for example, application/json).
Trait selector

:is(blob, string)

Any blob or string

Value type
string

The following example defines a video/quicktime blob:

namespace smithy.example

@mediaType("video/quicktime")
blob VideoData

Use cases

The primary function of the mediaType trait is to send open content data over the wire inside of values that are isolated from the rest of a payload using exact representations of customer provided data. While the model does define the serialization format of values able to be stored in a shape at design-time using a media type, models are not required to define any kind of schema for the shape.

The mediaType trait can be used to aid tools in documentation, validation, special-cased helpers to serialize and deserialize media type contents in code, assigning a fixed Content-Type when using HTTP bindings, etc.

Comparisons to document types

The serialization format of a shape marked with the @mediaType trait is an important part of its contract. In contrast, document types are serialized in a protocol-agnostic way and can only express data types as granular as the JSON-type system. Design-time media types are preferred over document types when the exact bytes of a value are required for an application to function.

6.4. timestampFormat trait#

Summary
Defines a custom timestamp serialization format.
Trait selector

:test(timestamp, member > timestamp)

timestamp or member that targets a timestamp

Value type
string

By default, the serialization format of a timestamp is implicitly determined by the protocol of a service; however, the serialization format can be explicitly configured in some protocols to override the default format using the timestampFormat trait.

Timestamp formats

Smithy defines the following built-in timestamp formats:

Format Description
date-time Date time as defined by the date-time production in RFC3339 section 5.6 with no UTC offset and optional fractional precision (for example, 1985-04-12T23:20:50.52Z). However, offsets are parsed gracefully, but the datetime is normalized to an offset of zero by converting to UTC.
http-date An HTTP date as defined by the IMF-fixdate production in RFC 7231#section-7.1.1.1 (for example, Tue, 29 Apr 2014 18:30:38 GMT). Note that in addition to the IMF-fixdate format specified in the RFC, implementations MUST also support optional fractional seconds (for example, Sun, 02 Jan 2000 20:34:56.000 GMT).
epoch-seconds Also known as Unix time, the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, with optional fractional precision (for example, 1515531081.1234).

Resolving timestamp formats

The following steps are taken to determine the serialization format of a member that targets a timestamp:

  1. Use the timestampFormat trait of the member, if present.
  2. Use the timestampFormat trait of the shape, if present.
  3. Use the default format of the protocol.

Important

This trait SHOULD NOT be used unless the intended serialization format of a timestamp differs from the default protocol format. Using this trait too liberally can cause other tooling to improperly interpret the timestamp.