Smithy RPC v2 CBOR protocol#
This specification defines the smithy.protocols#rpcv2Cbor
protocol. This
protocol is used to expose services that serialize RPC payloads as CBOR.
smithy.protocols#rpcv2Cbor
trait#
- Summary
- Adds support for an RPC-based protocol over HTTP that sends requests and responses with CBOR payloads.
- Trait selector
service
- Value type
- Structure
- See
- Protocol tests
smithy.protocols#rpcv2Cbor
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
smithy.protocols#rpcv2Cbor
.
$version: "2"
namespace smithy.example
use smithy.protocols#rpcv2Cbor
@rpcv2Cbor
service MyService {
version: "2020-07-02"
}
The following example defines a service that requires the use of
h2
when using event streams.
$version: "2"
namespace smithy.example
use smithy.protocols#rpcv2Cbor
@rpcv2Cbor(
http: ["h2", "http/1.1"],
eventStreamHttp: ["h2"]
)
service MyService {
version: "2020-02-05"
}
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 smithy.protocols#rpcv2Cbor
@rpcv2Cbor(
http: ["h2", "http/1.1"],
eventStreamHttp: ["h2", "http/1.1"]
)
service MyService {
version: "2020-02-05"
}
The following example defines a service that requires the use of
h2
for all requests, including event streams.
$version: "2"
namespace smithy.example
use smithy.protocols#rpcv2Cbor
@rpcv2Cbor(http: ["h2"])
service MyService {
version: "2020-02-05"
}
Supported traits#
The smithy.protocols#rpcv2Cbor
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. |
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. |
requestCompression | Indicates that an operation supports compressing requests from clients to services. |
Protocol behaviors#
Implementations of the smithy.protocols#rpcv2Cbor
protocol comply with the
following rules:
Requests#
Every request for the rpcv2Cbor
protocol MUST contain a Smithy-Protocol
header with the value of rpc-v2-cbor
.
Every request for the rpcv2Cbor
protocol MUST be sent using the HTTP
POST
method. HTTP binding traits MUST be ignored when
building rpcv2Cbor
requests if they are present.
Every request for the rpcv2Cbor
protocol MUST be sent to a URL with the
following form: {prefix?}/service/{serviceName}/operation/{operationName}
- The Smithy RPCv2 CBOR protocol will only use the last four segments of the
- URL when routing requests. For example, a service could use a
v1
prefix in the URL path, which would not affect the operation a request is routed to:v1/service/FooService/operation/BarOperation
- The
serviceName
segment MUST be replaced by theshape name
- of the service's Shape ID in the Smithy model. The
serviceName
produced by client implementations MUST NOT contain the namespace of theservice
shape. Service implementations SHOULD accept an absolute shape ID as the content of this segment with the#
character replaced with a.
character, routing it the same as if only the name was specified. For example, if theservice
's absolute shape ID iscom.example#TheService
, a service should accept bothTheService
andcom.example.TheService
as values for theserviceName
segment.
- The
- The
operationName
segment MUST be replaced by the name of theoperation
- shape in the Smithy. The
operationName
produced by client implementations MUST NOT contain the namespace of theoperation
shape. Service implementations MUST NOT accept an absolute shape ID as the content of this segment.
- The
Requests for the rpcv2Cbor
protocol MUST use the following behavior for
setting a Content-Type
header:
- Buffered RPC requests: the value of the
Content-Type
header MUST be application/cbor
.
- Buffered RPC requests: the value of the
- Event streaming requests: the value of the
Content-Type
header MUST be application/vnd.amazon.eventstream
.
- Event streaming requests: the value of the
- Requests for operations with no defined input type (as in, they target the
Unit
shape) MUST NOT contain bodies in their HTTP requests. TheContent-Type
for the serialization format MUST NOT be set.
Requests for the rpcv2Cbor
protocol MUST NOT contain an X-Amz-Target
or
X-Amzn-Target
header. An rpcv2Cbor
request is malformed if it contains
either of these headers. Server-side implementations MUST reject such requests
for security reasons.
Buffered RPC requests for the rpcv2Cbor
protocol SHOULD include a
Content-Length
header. Event streaming requests MUST NOT specify a content
length (instead using Transfer-Encoding: chunked
on HTTP/1.1).
Requests for the rpcv2Cbor
protocol MUST use the following behavior for
setting an Accept
header:
- For requests with event streaming responses: the value of the
Accept
- header MUST be
application/vnd.amazon.eventstream
.
- For requests with event streaming responses: the value of the
- For requests with all other response types: the value of the
Accept
- header MUST be
application/cbor
.
- For requests with all other response types: the value of the
Other forms of content streaming MAY be added in the future, utilizing
different values for Accept
.
In summary, the rpcv2Cbor
protocol defines behavior for the following
headers for requests:
Header | Status | Description |
---|---|---|
Smithy-Protocol |
Required | The value of rpc-v2-cbor . |
Content-Type |
Required with request bodies | The value of application/cbor . For event streaming requests, this
is application/vnd.amazon.eventstream . |
Content-Length |
Conditional | The standard Content-Length header defined by RFC 9110#section-8.6.
For event streaming requests, this MUST NOT be set. |
Accept |
Required | The value of application/cbor . For requests with event streaming
responses, this is application/vnd.amazon.eventstream . |
Responses#
The status code for successful rpcv2Cbor
responses MUST be 200
.
The status code for error rpcv2Cbor
MUST be determined by the following
steps:
- If the httpError trait is set on the error shape, its value is used.
- If the error trait is set to
server
, the value MUST be500
. - Otherwise, the value MUST be
400
.
Every response for the rpcv2Cbor
protocol MUST contain a Smithy-Protocol
header with the value of rpc-v2-cbor
. The response MUST match the value of
the Smithy-Protocol
header from the request.
Responses for the rpcv2Cbor
protocol MUST use the following behavior for
setting a Content-Type
header:
- Buffered RPC responses: the value of the
Content-Type
header MUST beapplication/cbor
. - Event streaming responses: the value of the
Content-Type
header MUST beapplication/vnd.amazon.eventstream
. - Responses for operations with no defined output type (as in, they target the
Unit
shape) MUST NOT contain bodies in their HTTP responses. TheContent-Type
for the serialization format MUST NOT be set.
Buffered RPC responses for the rpcv2Cbor
protocol SHOULD include a
Content-Length
header. Event streaming responses SHOULD NOT specify a
content length (instead using Transfer-Encoding: chunked
on HTTP/1.1).
Responses for the rpcv2Cbor
protocol SHOULD NOT contain the
X-Amzn-ErrorType
header. Type information is always serialized in the
payload. Clients MUST ignore this header. See Operation error serialization
for information on the serialization of error responses.
In summary, the rpcv2Cbor
protocol defines behavior for the following
headers for responses:
Header | Status | Description |
---|---|---|
Smithy-Protocol |
Required | The value of rpc-v2-cbor . |
Content-Type |
Required with response bodies | The value of application/cbor . For event streaming responses, this
is application/vnd.amazon.eventstream . |
Content-Length |
Conditional | The standard Content-Length header defined by RFC 9110#section-8.6.
For event streaming requests, this SHOULD NOT be set. |
Shape serialization#
The smithy.protocols#rpcv2Cbor
protocol serializes all shapes into a CBOR
document body with no HTTP bindings supported. The following table shows how
to convert each shape type:
Values that are null
MUST be omitted from wire contents where not subject
to default value serialization rules.
If an implementation does not support arbitrary precision (bigInteger
and
bigDecimal
Smithy types), it MUST fail when attempting to deserialize a
value of that type.
Note
The undefined
CBOR value, CBOR major type 7
value 23, is not supported. Clients SHOULD NOT
serialize to this CBOR value and SHOULD deserialize this CBOR value to
null
. Servers MUST NOT serialize to this CBOR value and MUST
deserialize this CBOR value to null
.
Numeric type serialization#
Numeric types (byte
, short
, integer
, long
, float
, and double
)
SHOULD be serialized into the smallest possible CBOR type representation that
can contain its value. For example, a field modeled as a long
with a value of
1 should be sent in a single byte.
Floating-point numeric types (float
and double
) MAY be serialized into
non-floating-point numeric types (byte
, short
, integer
, and long
) if
and only if the conversion would not cause a loss of precision. For example, a
field modeled as a float
with a value of 256 may be sent as an integer.
As support for half-precision floating-point values is inconsistent across implementations, floating-point numeric types SHOULD NOT serialize into a half-precision (16 bit) numeric CBOR values. Implementations MUST be capable of deserializing half-precision numeric CBOR values (including -Infinity, Infinity, and NAN) into their Smithy type representation.
Numeric types MUST be deserialized into their Smithy type representation. For
example, a field modeled as a long
with a single byte value of 1 must be
deserialized into a long.
Timestamp type serialization#
Timestamps are serialized as major type 6, value tag 1 (epoch-based date/time) to indicate the tagged value is an epoch timestamp. Values are either major type 0 (unsigned integer) or major type 1 (negative integer) for integer values or major type 7, value 25 (half-precision float), 26 (single-precision float), or 27 (double-precision float) for floating-point values.
As support for half-precision floating-point values is inconsistent across implementations, timestamp types SHOULD NOT serialize into a half-precision (16 bit) numeric CBOR value for the tagged value.
This protocol uses epoch-seconds
, also known as Unix timestamps, with
millisecond (1/1000th of a second) resolution. The timestampFormat
MUST NOT be respected to customize timestamp serialization.
Default value serialization#
To avoid information disclosure, service serializers SHOULD omit the default value of structure members that are marked with the internal trait.
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.
Operation response deserialization#
Clients MUST use the following rules to interpret responses and determine how to deserialize them:
- If the response does not have the same
Smithy-Protocol
header as the - request, it MUST be considered malformed. Clients who receive a malformed response MUST handle it (i.e. throw a reasonable exception) based solely on the HTTP response code. No attempt should be made to interpret the response body or headers.
- If the response does not have the same
- If the response code is
200
, the request is successful and the response - payload SHALL be deserialized as the
output
shape defined on the operation.
- If the response code is
- Finally, if the response code is not
200
, the response payload is an - exception and SHALL be deserialized according to Operation error serialization
- Finally, if the response code is not
Operation error serialization#
Error responses in the rpcv2Cbor
protocol MUST be serialized identically to
standard responses with one additional component to distinguish which error is
contained: a body field named __type
. This value of this component MUST
contain the error’s absolute Shape ID.
By default, all error shapes have a message
field containing an
error-specific message meant for human consumers of API errors. Services MUST
support generating this field and serializing it when responding. Clients MUST
support generating this field and deserializing it from responses.
The Code
response body field and code
response body field MUST NOT be
used to distinguish which error is contained in a response.
Clients who receive a malformed error response MUST handle it based solely on the HTTP response code (i.e. throw a reasonable exception). No attempt should be made to interpret the response body or headers.
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).