Skip to content

Commit

Permalink
Add clarifications on how to use mediaType trait
Browse files Browse the repository at this point in the history
This commit clarifies what the mediaType trait is used for, the fact
that it's a design-time contract, and adds a missing header
serialization test to ensure that mediaType trait strings are base64
encoded.
  • Loading branch information
mtdowling committed Jul 16, 2020
1 parent de4dd08 commit 371cbdf
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 8 deletions.
49 changes: 42 additions & 7 deletions docs/source/1.0/spec/core/protocol-traits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -209,28 +209,63 @@ following document:
-------------------

Summary
Describes the contents of a blob or string shape using a media type as
defined by :rfc:`6838` (e.g., "video/quicktime").
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 ``mediaType`` can be used in tools for documentation, validation,
automated conversion or encoding in code, automatically determining an
appropriate Content-Type for an HTTP-based protocol, etc.

The following example defines a video/quicktime blob:
The following example defines a ``video/quicktime`` blob:

.. tabs::

.. code-tab:: smithy

namespace smithy.example

@mediaType("video/quicktime")
blob VideoData

.. code-tab:: json

{
"smithy": "1.0",
"shapes": {
"smithy.example#VideoData": {
"type": "blob",
"traits": {
"smithy.api#mediaType": "video/quicktime"
}
}
}
}

.. rubric:: 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
:ref:`HTTP bindings <http-traits>`, etc.

.. rubric:: 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.


.. _timestampFormat-trait:

Expand Down
56 changes: 55 additions & 1 deletion smithy-aws-protocol-tests/model/restJson1/http-headers.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ structure NullAndEmptyHeadersIO {
c: StringList,
}

/// The example tests how timestamp request and response headers are serialized.
/// This example tests how timestamp request and response headers are serialized.
@http(uri: "/TimestampFormatHeaders", method: "POST")
operation TimestampFormatHeaders {
input: TimestampFormatHeadersIO,
Expand Down Expand Up @@ -413,3 +413,57 @@ structure TimestampFormatHeadersIO {
@httpHeader("X-targetDateTime")
targetDateTime: DateTime,
}

/// This example ensures that mediaType strings are base64 encoded in headers.
@readonly
@http(uri: "/MediaTypeHeader", method: "GET")
operation MediaTypeHeader {
input: MediaTypeHeaderInput,
output: MediaTypeHeaderOutput
}

apply MediaTypeHeader @httpRequestTests([
{
id: "MediaTypeHeaderInputBase64",
documentation: "Headers that target strings with a mediaType are base64 encoded",
protocol: restJson1,
method: "GET",
uri: "/MediaTypeHeader",
headers: {
"X-Json": "dHJ1ZQ=="
},
body: "",
params: {
json: "true"
}
},
])

apply MediaTypeHeader @httpResponseTests([
{
id: "MediaTypeHeaderOutputBase64",
documentation: "Headers that target strings with a mediaType are base64 encoded",
protocol: restJson1,
code: 200,
headers: {
"X-Json": "dHJ1ZQ=="
},
body: "",
params: {
json: "true"
}
},
])

structure MediaTypeHeaderInput {
@httpHeader("X-Json")
json: JsonValue,
}

structure MediaTypeHeaderOutput {
@httpHeader("X-Json")
json: JsonValue,
}

@mediaType("application/json")
string JsonValue
1 change: 1 addition & 0 deletions smithy-aws-protocol-tests/model/restJson1/main.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ service RestJson {
NullAndEmptyHeadersClient,
NullAndEmptyHeadersServer,
TimestampFormatHeaders,
MediaTypeHeader,

// @httpLabel tests
HttpRequestWithLabels,
Expand Down

0 comments on commit 371cbdf

Please sign in to comment.