AWS restJson1 protocol#

This specification defines the aws.protocols#restJson1 protocol. This protocol is used to expose services that serialize payloads as JSON and utilize features of HTTP like configurable HTTP methods, URIs, and status codes.

aws.protocols#restJson1 trait#

Summary
A protocol definition trait that configures a service to support the aws.protocols#restJson1 protocol.
Trait selector
service
Value type
Structure

aws.protocols#restJson1 is a structure that supports the following members:

Property Type Description
http [string] The priority ordered list of supported HTTP protocol versions.
eventStreamHttp [string] The priority ordered list of supported HTTP protocol versions that are required when using event streams with the service. If not set, this value defaults to the value of the http member. Any entry in eventStreamHttp MUST also appear in http.

Each entry in http and eventStreamHttp SHOULD be a valid Application-Layer Protocol Negotiation (ALPN) Protocol ID (for example, http/1.1, h2, etc). Clients SHOULD pick the first protocol in the list they understand when connecting to a service. A client SHOULD assume that a service supports http/1.1 when no http or eventStreamHttp values are provided.

The following example defines a service that uses aws.protocols#restJson1.

$version: "2"

namespace smithy.example

use aws.protocols#restJson1

@restJson1
service MyService {
    version: "2020-04-02"
}

The following example defines a service that requires the use of h2 when using event streams.

$version: "2"

namespace smithy.example

use aws.protocols#restJson1

@restJson1(
    http: ["h2", "http/1.1"],
    eventStreamHttp: ["h2"]
)
service MyService {
    version: "2020-04-02"
}

The following example defines a service that requires the use of h2 or http/1.1 when using event streams, where h2 is preferred over http/1.1.

$version: "2"

namespace smithy.example

use aws.protocols#restJson1

@restJson1(
    http: ["h2", "http/1.1"],
    eventStreamHttp: ["h2", "http/1.1"]
)
service MyService {
    version: "2020-04-02"
}

The following example defines a service that requires the use of h2 for all requests, including event streams.

$version: "2"

namespace smithy.example

use aws.protocols#restJson1

@restJson1(http: ["h2"])
service MyService {
    version: "2020-04-02"
}

Supported traits#

The aws.protocols#restJson1 protocol supports the following traits that affect serialization:

Trait Description
cors Indicates that the service supports CORS.
endpoint Configures a custom operation endpoint.
hostLabel Binds a top-level operation input structure member to a label in the hostPrefix of an endpoint trait.
http Configures the HTTP bindings of an operation. An operation bound to a service with this protocol applied MUST have the http trait applied.
httpError A client error has a default status code of 400, and a server error has a default status code of 500. The httpError trait is used to define a custom status code.
httpHeader Binds a top-level input, output, or error structure member to an HTTP header instead of the payload.
httpLabel Binds a top-level input structure member to a URI label instead of the payload.
httpPayload

Binds a top-level input or output structure member as the payload of a request or response.

Important

This protocol only permits the httpPayload trait to be applied to members that target structures, documents, strings, blobs, or unions.

httpPrefixHeaders Binds a top-level input, output, or error member to a map of prefixed HTTP headers.
httpQuery Binds a top-level input structure member to a query string parameter.
httpQueryParams Binds a map of key-value pairs to query string parameters.
httpChecksumRequired Indicates that requests MUST send a checksum.
jsonName By default, the JSON property names used in serialized structures are the same as a structure member name. The jsonName trait changes the JSON property name to a custom value.
timestampFormat Defines a custom timestamp serialization format.
requestCompression Indicates that an operation supports compressing requests from clients to services.

Content-Type#

The aws.protocols#restJson1 protocol uses a default Content-Type of application/json.

Input or output shapes that apply the httpPayload trait on one of their top-level members MUST use a Content-Type that is appropriate for the payload. The following table defines the expected Content-Type header for requests and responses based on the shape targeted by the member marked with the httpPayload trait:

Targeted shape Content-Type
Has mediaType trait Use the value of the mediaType trait if present.
string text/plain
blob application/octet-stream
document application/json
structure application/json
union application/json

Default value serialization#

  1. To avoid information disclosure, serializers SHOULD omit the default value of structure members that are marked with the internal trait.
  2. Client deserializers SHOULD attempt to error correct structures that omit a @required member by filling in a default zero value for the member. Error correction allows clients to continue to function while the server is in error.

JSON shape serialization#

Smithy type JSON type
blob JSON string value that is base64 encoded.
boolean JSON boolean
byte JSON number
short JSON number
integer JSON number
long JSON number
float JSON number for numeric values. JSON strings for NaN, Infinity, and -Infinity
double JSON number for numeric values. JSON strings for NaN, Infinity, and -Infinity
bigDecimal JSON number. Unfortunately, this protocol serializes bigDecimal shapes as a normal JSON number. Many JSON parsers will either truncate the value or be unable to parse numbers that exceed the size of a double.
bigInteger JSON number. Unfortunately, this protocol serializes bigInteger shapes as a normal JSON number. Many JSON parsers will either truncate the value or be unable to parse numbers that exceed the size of a double.
string JSON string
timestamp JSON number (default). This protocol uses epoch-seconds, also known as Unix timestamps, in JSON payloads represented as a double. However, the timestampFormat MAY be used to customize timestamp serialization.
document Any JSON value
list JSON array
set JSON array. A set is serialized identically as a list shape, but only contains unique values.
map JSON object
structure JSON object. Each member value provided for the structure is serialized as a JSON property where the property name is the same as the member name. The jsonName trait can be used to serialize a property using a custom name.
union JSON object. A union is serialized identically as a structure shape, but only a single member can be set to a non-null value. Deserializers MUST ignore an unrecognized __type member if present.

HTTP binding serialization#

The aws.protocols#restJson1 protocol supports all of the HTTP binding traits defined in the HTTP protocol bindings specification. The serialization formats and behaviors described for each trait are supported as defined in the aws.protocols#restJson1 protocol.

Non-numeric float and double serialization#

Smithy floats and doubles are defined by IEEE-754, which includes special values for "not a number" and both positive and negative infinity. Unless otherwise specified, the aws.protocols#restJson1 protocol treats those special values as strings with the following values:

Special Value String Value
Not a number NaN
Positive infinity Infinity
Negative infinity -Infinity

Operation error serialization#

Error responses in the restJson1 protocol are serialized identically to standard responses with one additional component to distinguish which error is contained. New server-side protocol implementations MUST use a header field named X-Amzn-Errortype. Clients MUST accept any one of the following: an additional header with the name X-Amzn-Errortype, a body field with the name __type, or a body field named code. The value of this component SHOULD contain only the shape name of the error's Shape ID.

Legacy server-side protocol implementations sometimes include additional information in this value. New server-side protocol implementations SHOULD NOT populate this value with anything but the shape name. All client-side implementations SHOULD support sanitizing the value to retrieve the disambiguated error type using the following steps:

  1. If a : character is present, then take only the contents before the first : character in the value.
  2. If a # character is present, then take only the contents after the first # character in the value.

All of the following error values resolve to FooError:

  • FooError
  • FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/
  • aws.protocoltests.restjson#FooError
  • aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/

Protocol compliance tests#

A full compliance test suite is provided and SHALL be considered a normative reference: https://github.com/smithy-lang/smithy/tree/main/smithy-aws-protocol-tests/model/restJson1

These compliance tests define a model that is used to define test cases and the expected serialized HTTP requests and responses for each case.

TODO: Add event stream handling specifications.

Error shape renaming#

By default, Smithy permits renaming shapes to disambiguate shape ID conflicts in the service closure via the rename property. However, services using this protocol are not allowed to rename error shapes (shapes with error trait applied).

Client-side implementations rely on the response body field code or __type to resolve the error type. Server-side implementations of this protocol will only send the shape name for the response body field.

When there are conflicting shape IDs smithy.service#ServiceError and smithy.other#ServiceError, the server will only send the shape name ServiceError. Clients will not be able to resolve the correct error type without the namespace.

Server-side implementations of this protocol don't serialize renamed shape names. As a result, renaming will not resolve the conflicting shape IDs issue, and hence it is not permitted.