AWS query protocol#
This document defines the aws.protocols#awsQuery protocol.
Overview#
The AWS Query protocol uses HTTP and serializes HTTP requests using query
string parameters and responses using XML. Requests can be sent using GET
requests and placing parameters in the query string; however, sending
requests using POST with an application/x-www-form-urlencoded
Content-Type is preferred because some proxies, clients, and servers have
limitations around the maximum amount of data that can be sent in a query
string.
A service is configured to use this protocol by applying the aws.protocols#awsQuery trait. The service MUST also define the xmlNamespace trait which is used to determine the XML namespace used in XML responses.
$version: "2"
namespace smithy.example
use aws.protocols#awsQuery
@awsQuery
@xmlNamespace(uri: "http://foo.com")
service MyService {
    version: "2020-02-05"
}
Important
- This protocol is deprecated and SHOULD NOT be used for any new service.
- This protocol does not support document types.
- This protocol does not support HTTP binding traits. HTTP binding traits MUST be ignored if they are present.
- This protocol does not support any kind of streaming requests or responses, including event streams.
Supported traits#
The aws.protocols#awsQuery 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. | 
| xmlAttribute | Serializes an object property as an XML attribute rather than a nested XML element. | 
| xmlFlattened | By default, entries in lists, sets, and maps have values serialized in
nested elements specific to their type. The xmlFlattenedtrait
unwraps these elements into the containing structure. | 
| xmlName | By default, the XML element names and form-urlencoded key segments used
in serialized structures are the same as a structure member name. The xmlNametrait changes these names to a custom value.  See
Query key resolution for more information. | 
| xmlNamespace | Adds an xmlns namespace definition URI to XML element(s) generated for the targeted shape. | 
| timestampFormat | Defines a custom timestamp serialization format. | 
| awsQueryError | Provides a custom "Code" value for awsQueryerrors and an HTTP response code.
The "Code" of anawsQueryerror is used by clients to determine
which type of error was encountered. | 
| requestCompression | Indicates that an operation supports compressing requests from clients to services. | 
Default value serialization#
- To avoid information disclosure, 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 @requiredmember by filling in a default zero value for the member. Error correction allows clients to continue to function while the server is in error.
Request serialization#
Requests SHALL be sent to the root URL (/). Requests SHALL use a POST
request and a body that contains input parameters serialized with a
Content-Type of application/x-www-form-urlencoded. All keys and
values MUST be encoded according to RFC 3986. Requests SHALL contain
a Content-Length header; this protocol does not support chunked
Transfer-Encoding.
Requests MUST include the following key value pairs in the serialized body:
| Key | Value | 
|---|---|
| Action | The shape nameof the operation's Shape ID. | 
| Version | The value of the "version" property of the service. | 
These, along with other input members, are serialized in the request body, concatenated with the following rules:
- "&" is used to separate member key-value pairs.
- "=" is used to separate member keys from values.
- "." is used to separate member name segments within keys.
x-www-form-urlencoded shape serialization#
Simple shapes are serialized according to the following rules:
| Smithy type | Request entity | 
|---|---|
| blob | Text value that is base64 encoded. | 
| boolean | Text value of either "true" or "false". | 
| byte | Text value of the number. | 
| short | Text value of the number. | 
| integer | Text value of the number. | 
| long | Text value of the number. | 
| float | Text value of the number. | 
| double | Text value of the number. | 
| bigDecimal | Text value of the number, using scientific notation if an exponent is needed. Unfortunately, many parsers will either truncate the value or be unable to parse numbers that exceed the size of a double. | 
| bigInteger | Text value of the number, using scientific notation if an exponent is needed. Unfortunately, many parsers will either truncate the value or be unable to parse numbers that exceed the size of a double. | 
| string | UTF-8 value of the string. Empty strings are serialized as empty
values, meaning a Foomember set to an empty string would be
serialized as "&Foo=". | 
| timestamp | Text value of the timestamp. This protocol uses date-timeas the
default serialization. However, the timestampFormat
MAY be used to customize timestamp serialization. | 
| document | Undefined. Document shapes are not supported in this protocol. | 
Aggregate shapes are serialized with additional segments for members appended to the input's key.
| Smithy type | Request entity | 
|---|---|
| list | Each value provided in the list is serialized as a separate key with
a "." separator, the string "member", a "." separator, and a "1" indexed
incrementing counter appended to the container's key.
The xmlName trait can be used to serialize a property using a custom name instead of "member". The xmlFlattened trait
can be used to unwrap the values into a containing structure or union,
with the key not containing the initial "." separator and membersegment. | 
| map | Each key and value in each pair provided in the map is serialized as a separate key with a "." separator, the string "entry", a "." separator, a "1" indexed incrementing counter, a "." separator, and the string "key" or "value" (for member keys or values, respectively) appended to the container's key. The xmlName trait can be used to serialize a property using a custom name instead of "member", "key", or "value". The xmlFlattened trait can be used to unwrap the values into a containing structure or union, with the key not containing the initial "." separator and "entry" segment. | 
| structure | Each member value provided for the shape is serialized as a separate key with a "." separator and the member name appended to the container's key. The xmlName trait can be used to serialize a property using a custom name. Members with null values are not serialized. | 
| union | A union is serialized identically to a structureshape, but only a
single member can be set to a non-null value. | 
Query key resolution#
The key component used to serialize a member in a request in awsQuery is
resolved using the following process:
- Use the value of the xmlName trait applied to the member, if present. 
- Use the default value for the member: - Member location - Default value - listmember- The string literal "member" - mapkey- The string literal "key" - mapvalue- The string literal "value" - structuremember- The - member name- unionmember- The - member name
Example requests#
The following list of examples are non-exhaustive. See the
Protocol compliance tests for a suite of compliance tests for the
awsQuery protocol. Newlines have been to examples only for readability.
Structures and unions#
Each member value provided for the shape is serialized as a separate key with a "." separator and the member name appended to the container's key. The xmlName trait can be used to serialize a property using a custom name. Members with null values are not serialized.
For example, given the following:
@input
structure QueryStructuresInput {
    foo: String
    @xmlName("Custom")
    bar: String
    baz: MyStructure
}
structure MyStructure {
    temp: String
}
The application/x-www-form-urlencoded serialization is:
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: ...
Host: example.com
Action=QueryStructures
&Version=2020-07-02
&foo=example1
&Custom=example2
&baz.temp=example3
Collections#
Each value provided in the list is serialized as a separate key with
a "." separator, the string "member", a "." separator, and a "1" indexed
incrementing counter appended to the container's key.
The xmlName trait can be used to serialize a property using a custom name instead of "member". The xmlFlattened trait
can be used to unwrap the values into a containing structure or union,
with the key not containing the initial "." separator and member
segment.
For example, given the following:
@input
structure QueryListsInput {
    ListArg: StringList
    ComplexListArg: GreetingList
    @xmlFlattened
    FlattenedListArg: StringList
    ListArgWithXmlNameMember: ListWithXmlName
    // Notice that the xmlName on the targeted list member is ignored.
    @xmlFlattened
    @xmlName("Hi")
    FlattenedListArgWithXmlName: ListWithXmlName
}
list ListWithXmlName {
    @xmlName("item")
    member: String
}
list StringList {
    member: String
}
list GreetingList {
    member: GreetingStruct
}
structure GreetingStruct {
    hi: String
}
The application/x-www-form-urlencoded serialization is:
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: ...
Host: example.com
Action=QueryLists
&Version=2020-07-02
&ListArg.member.1=foo
&ListArg.member.2=bar
&ListArg.member.3=baz
&ComplexListArg.member.1.hi=hello
&ComplexListArg.member.2.hi=hola
&FlattenedListArg.1=A
&FlattenedListArg.2=B
&ListArgWithXmlNameMember.item.1=A
&ListArgWithXmlNameMember.item.2=B
&Hi.1=A
&Hi.2=B
Maps#
Each key and value in each pair provided in the map is serialized as a separate key with a "." separator, the string "entry", a "." separator, a "1" indexed incrementing counter, a "." separator, and the string "key" or "value" (for member keys or values, respectively) appended to the container's key. The xmlName trait can be used to serialize a property using a custom name instead of "member", "key", or "value". The xmlFlattened trait can be used to unwrap the values into a containing structure or union, with the key not containing the initial "." separator and "entry" segment.
For example, given the following:
@input
structure QueryMapsInput {
    MapArg: StringMap
    @xmlName("reNamed")
    RenamedMapArg: StringMap
    ComplexMapArg: ComplexMap
    MapWithXmlMemberName: MapWithXmlName
}
map StringMap {
    key: String
    value: String
}
map ComplexMap {
    key: String
    value: GreetingStruct
}
map MapWithXmlName {
    @xmlName("K")
    key: String
    @xmlName("V")
    value: String
}
structure GreetingStruct {
    hi: String
}
The application/x-www-form-urlencoded serialization is:
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: ...
Host: example.com
Action=QueryMaps
&Version=2020-07-02
&MapArg.entry.1.key=bar
&MapArg.entry.1.value=Bar
&MapArg.entry.2.key=foo
&MapArg.entry.2.value=Foo
&reNamed.entry.1.key=foo
&reNamed.entry.1.value=Foo
&ComplexMapArg.entry.1.key=bar
&ComplexMapArg.entry.1.value.hi=Bar
&ComplexMapArg.entry.2.key=foo
&ComplexMapArg.entry.2.value.hi=Foo
&MapWithXmlMemberName.entry.1.K=bar
&MapWithXmlMemberName.entry.1.V=Bar
&MapWithXmlMemberName.entry.2.K=foo
&MapWithXmlMemberName.entry.2.V=Foo
Response serialization#
The awsQuery protocol serializes XML responses within an XML root node with
the name of the operation's output suffixed with "Response". A nested element,
with the name of the operation's output suffixed with "Result", contains the
contents of the successful response. A nested element named "ResponseMetadata"
contains a nested element named "RequestId" that contains a unique identifier
for the associated request.
The value of the uri member of the xmlNamespace trait
is serialized in an xmlns attribute on the response's XML root node. The
following is a sample response to an operation named XmlTest.
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Content-Type: text/xml
Content-Length: ...
<XmlTestResponse xmlns="https://example.com/">
    <XmlTestResult>
        <testValue>Hello!</testValue>
    </XmlTestResult>
    <ResponseMetadata>
        <RequestId>c6104cbe-af31-11e0-8154-cbc7ccf896c7</RequestId>
    </ResponseMetadata>
</XmlTestResponse>
XML shape serialization#
| Smithy type | XML entity | 
|---|---|
| blob | XML text node with a value that is base64 encoded. | 
| boolean | XML text node with a value either "true" or "false". | 
| byte | XML text node with a value of the number. | 
| short | XML text node with a value of the number. | 
| integer | XML text node with a value of the number. | 
| long | XML text node with a value of the number. | 
| float | XML text node with a value of the number. | 
| double | XML text node with a value of the number. | 
| bigDecimal | XML text node with a value of the number, using scientific notation if an exponent is needed. Unfortunately, many XML parsers will either truncate the value or be unable to parse numbers that exceed the size of a double. | 
| bigInteger | XML text node with a value of the number, using scientific notation if an exponent is needed. Unfortunately, many XML parsers will either truncate the value or be unable to parse numbers that exceed the size of a double. | 
| string | XML text node with an XML-safe, UTF-8 value of the string. | 
| timestamp | XML text node with a value of the timestamp. This protocol uses date-timeas the default serialization. However, the
timestampFormat MAY be used to
customize timestamp serialization. | 
| document | Undefined. Document shapes are not supported in this protocol. | 
| list | XML element. Each value provided in the list is serialized as a nested
XML element with the name member. The xmlName trait can be
used to serialize a property using a custom name. The
xmlFlattened trait can be used to unwrap the values into a
containing structure or union, with the value XML element using the
structure or union member name. See List serialization
for more. | 
| map | XML element. Each key-value pair provided in the map is serialized in
a nested XML element with the name entrythat contains nested
elementskeyandvaluefor the pair. The xmlName trait
can be used to serialize key or value properties using a custom name,
it cannot be used to influence theentryname. The
xmlFlattened trait can be used to unwrap the entries into a
containing structure or union, with the entry XML element using the
structure or union member name. See Map serialization for
more. | 
| structure | XML element. Each member value provided for the structure is serialized as a nested XML element where the element name is the same as the member name. The xmlName trait can be used to serialize a property using a custom name. The xmlAttribute trait can be used to serialize a property in an attribute of the containing element. See Structure and union serialization for more. | 
| union | XML element. A union is serialized identically to a structureshape, but only a single member can be set to a non-null value. | 
Important
See XML bindings for comprehensive documentation, including examples and behaviors when using multiple XML traits.
Operation error serialization#
Error response bodies in the awsQuery protocol are wrapped within an XML
root node named ErrorResponse. A nested element, named Error, contains
the serialized error structure members. The HTTP response code is a
resolved value.
HTTP/1.1 400 Bad Request
Date: Mon, 27 Jul 2009 12:28:53 GMT
Content-Type: text/xml
Content-Length: ...
<ErrorResponse>
    <Error>
        <Type>Sender</Type>
        <Code>InvalidGreeting</Code>
        <Message>Hi</Message>
        <AnotherSetting>setting</AnotherSetting>
    </Error>
    <RequestId>c6104cbe-af31-11e0-8154-cbc7ccf896c7</RequestId>
</ErrorResponse>
Error responses contain the following nested elements:
- Error: A container for the encountered error.
- Type: One of "Sender" or "Receiver"; whomever is at fault from the service perspective.
- Code: The resolved error code value that is used to distinguish which specific error is serialized in the response.
- RequestId: Contains a unique identifier for the associated request.
In the above example, Message, and AnotherSetting are additional,
hypothetical members of the serialized error structure.
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 awsQuery 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 | 
Error HTTP response status code resolution#
The status code of an error is 400, 500, or a custom status code
defined by the aws.protocols#awsQueryError trait. The status code
is determined through the following process:
- Use the value of the httpResponseCodemember of the aws.protocols#awsQueryError trait applied to the error structure, if present.
- Use the value 400if the value of the error trait is"client".
- Use the value 500.
Error "Code" resolution#
The value of the "Code" element serialized in the error is resolved using the following process:
- Use the value of the codemember of the aws.protocols#awsQueryError trait applied to the error structure, if present.
- The shape nameof the error's Shape ID.
aws.protocols#awsQuery trait#
- Summary
- Adds support for the awsQuery protocol to a service. The service MUST have an xmlNamespace trait.
- Trait selector
- service [trait|xmlNamespace]- Service shapes with the xmlNamespace trait 
- Value type
- Annotation trait.
- See
- Protocol tests
$version: "2"
namespace smithy.example
use aws.protocols#awsQuery
@awsQuery
@xmlNamespace(uri: "http://foo.com")
service MyService {
    version: "2020-02-05"
}
aws.protocols#awsQueryError trait#
- Summary
- Provides a custom "Code" value for
awsQueryerrors and an HTTP response code. The "Code" of anawsQueryerror is used by clients to determine which type of error was encountered.
- Trait selector
- structure [trait|error]- The - awsQueryErrortrait can only be applied to structure shapes that also have the error trait.
- Value type
- structurethat supports the following members:- Property - Type - Description - code - string- Required The value used to distinguish this error shape during client deserialization. - httpResponseCode - integer- Required The HTTP response code used on a response that contains this error shape. 
Important
The aws.protocols#awsQueryError trait is only used when serializing
operation errors using the aws.protocols#query protocol. Unless
explicitly stated in other Smithy protocol specification, this trait has
no impact on other Smithy protocols.
The following example defines an error that uses a custom "Code" of "InvalidThing" and an HTTP status code of 400.
$version: "2"
namespace smithy.example
use aws.protocols#awsQueryError
@awsQueryError(
    code: "InvalidThing",
    httpResponseCode: 400,
)
@error("client")
structure InvalidThingException {
    message: String
}
aws.protocols#awsQueryCompatible trait#
- Summary
- When using the awsQuery protocol, custom - Codeand- HTTP response codevalues can be defined for an error response via the awsQueryError trait.- The - awsQueryCompatibletrait allows services to backward compatibly migrate from- awsQueryto awsJson1_0 without removing values defined in the- awsQueryErrortrait.- This trait adds the - x-amzn-query-errorheader in the form of- Code;Faultto error responses.- Codeis the value defined in the awsQueryError, and- Faultis one of- Senderor- Receiver.
- Trait selector
- service :test([trait|aws.protocols#awsJson1_0], [trait|smithy.protocols#rpcv2Cbor])
- Value type
- Annotation trait
$version: "2"
use aws.protocols#awsQueryCompatible
use aws.protocols#awsQueryError
use aws.protocols#awsJson1_0
@awsQueryCompatible
@awsJson1_0
service MyService {
    version: "2020-02-05"
}
@awsQueryError(
    code: "InvalidThing",
    httpResponseCode: 400,
)
@error("client")
structure InvalidThingException {
    message: String
}
Important
AWS client implementations of the smithy.protocols#rpcv2Cbor protocol
MUST support the aws.protocols#awsQueryCompatible trait.
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/awsQuery
These compliance tests define a model that is used to define test cases and the expected serialized HTTP requests and responses for each case.
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.