From b8b3f2b2c2bed74c5fbc09486da803e5d6c83c37 Mon Sep 17 00:00:00 2001 From: kstich Date: Mon, 1 Feb 2021 18:46:41 -0800 Subject: [PATCH 1/2] Document awsQuery protocol This fleshes out the documentation for the `awsQuery` protocol. --- .../1.0/spec/aws/aws-query-protocol.rst | 320 +++++++++++++++++- .../1.0/spec/aws/aws-restxml-protocol.rst | 10 +- docs/themes/smithy/static/default.css_t | 2 +- .../META-INF/smithy/aws.protocols.json | 6 +- 4 files changed, 325 insertions(+), 13 deletions(-) diff --git a/docs/source/1.0/spec/aws/aws-query-protocol.rst b/docs/source/1.0/spec/aws/aws-query-protocol.rst index 93e1d6a239d..b3a9425888f 100644 --- a/docs/source/1.0/spec/aws/aws-query-protocol.rst +++ b/docs/source/1.0/spec/aws/aws-query-protocol.rst @@ -19,8 +19,8 @@ This specification defines the ``aws.protocols#awsQuery`` protocol. -------------------------------- Summary - Adds support for an HTTP protocol that sends requests in the query - string and responses in XML documents. + Adds support for an HTTP protocol that sends "POST" requests in the body + as ``x-www-form-urlencoded`` strings and responses in XML documents. Trait selector ``service [trait|xmlNamespace]`` @@ -58,13 +58,323 @@ See } } +---------------- +Supported traits +---------------- + +The ``aws.protocols#awsQuery`` protocol supports the following traits +that affect serialization: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Trait + - Description + * - :ref:`cors ` + - Indicates that the service supports CORS. + * - :ref:`xmlAttrubute ` + - Serializes an object property as an XML attribute rather than a nested + XML element. + * - :ref:`xmlFlattened ` + - By default, entries in lists, sets, and maps have values serialized in + nested elements specific to their type. The ``xmlFlattened`` trait + unwraps these elements into the containing structure. + * - :ref:`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 + ``xmlName`` trait changes the XML element name to a custom value. + * - :ref:`xmlNamespace ` + - Adds an xmlns namespace definition URI to XML element(s) generated + for the targeted shape. + * - :ref:`timestampFormat ` + - Defines a custom timestamp serialization format. + .. important:: This protocol does not support document types. + +----------------- +Protocol Behavior +----------------- + +Every request for the ``awsQuery`` protocol MUST be sent to the +root URL (``/``) using the HTTP "POST" method. + +The ``awsQuery`` protocol does not support custom HTTP bindings. +:ref:`HTTP binding traits ` MUST be ignored if they are present. + +The ``awsQuery`` protocol uses the following headers: + +.. list-table:: + :header-rows: 1 + :widths: 20 20 80 + + * - Header + - Required + - Description + * - ``Content-Type`` + - true + - This header uses the static values of ``application/x-www-form-urlencoded`` + for requests and ``text/xml`` for responses. + * - ``Content-Length`` + - true + - The standard ``Content-Length`` header defined by + `RFC 7230 Section 3.3.2`_. + + +--------------------- +Request serialization +--------------------- + +The ``awsQuery`` protocol serializes inputs in ``x-www-form-urlencoded`` +request bodies. All keys and values MUST be encoded according to :rfc:`3986`. +Requests MUST have the following key value pairs added to the inputs in the +serialized body: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Key + - Value + * - ``Action`` + - The name of the operation. + * - ``Version`` + - The value of the :ref:`"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 parameter key-value pairs. +* "=" is used to separate parameter names from values. +* "." is used to separate nested parameter name segments. + +x-www-form-urlencoded shape serialization +----------------------------------------- + +Simple shapes are serialized according to the following rules: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - 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. + * - ``timestamp`` + - Text value of the timestamp. This protocol uses ``date-time`` as the + default serialization. However, the :ref:`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. + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Smithy type + - Request entity + * - ``list`` + - Each value provided in the list is serialized as a separate key with + a "." separator, ``member``, a "." separator, and a ``1`` indexed + incrementing counter appended to the container's key. The :ref:`xmlName-trait` + can be used to serialize a property using a custom name instead of + ``member``. The :ref:`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. + * - ``set`` + - A set is serialized identically as a ``list`` shape, but only contains + unique values. + * - ``map`` + - Each key and value in each pair provided in the map is serialized as a + separate key with a "." separator, ``entry``, a "." separator, a ``1`` + indexed incrementing counter, a "." separator, and a ``key`` or + ``value`` segment appended to the container's key. The :ref:`xmlName-trait` + can be used to serialize a property using custom names instead of + ``member``, ``key``, or ``value``. The :ref:`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 structure is serialized as a + separate key with a "." separator and the member name appended to the + container's key. The :ref:`xmlName-trait` can be used to serialize a + property using a custom name. + * - ``union`` + - A union is serialized identically as a ``structure`` shape, but only a + single member can be set to a non-null value. + + +---------------------- +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. + +The value of the ``uri`` member of the :ref:`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``. + +.. code-block:: xml + + + + Hello! + + + + +XML shape serialization +----------------------- + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - 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-time`` as the default serialization. However, the + :ref:`timestampFormat ` MAY be used to + customize timestamp serialization. + * - ``document`` + - Undefined. Document shapes are not recommended for use in XML based + protocols. + * - ``list`` + - XML element. Each value provided in the list is serialized as a nested + XML element with the name ``member``. The :ref:`xmlName-trait` can be + used to serialize a property using a custom name. The + :ref:`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. + * - ``set`` + - XML element. A set is serialized identically as a ``list`` shape, + but only contains unique values. + * - ``map`` + - XML element. Each key-value pair provided in the map is serialized in + a nested XML element with the name ``entry`` that contains nested + elements ``key`` and ``value`` for the pair. The :ref:`xmlName-trait` + can be used to serialize key or value properties using a custom name, + it cannot be used to influence the ``entry`` name. The + :ref:`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. + * - ``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 :ref:`xmlName-trait` can be used to + serialize a property using a custom name. The :ref:`xmlAttribute-trait` + can be used to serialize a property in an attribute of the containing + element. + * - ``union`` + - XML element. A union is serialized identically as a ``structure`` + shape, but only a single member can be set to a non-null value. + .. important:: - This protocol only permits the :ref:`httpPayload-trait` to be applied to - members that target structures, documents, strings, blobs, or unions. + See :ref:`serializing-xml-shapes` for comprehensive documentation, + including examples and behaviors when using multiple XML traits. + + +.. _awsQuery-errors: + +----------------------------- +Operation error serialization +----------------------------- + +Error responses in the ``awsQuery`` protocol are wrapped within an XML root +node named ``ErrorResponse``. A nested element, named ``Error``, contains the +serialized error structure members. + +Serialized error shapes MUST also contain an additional child element ``Code`` +that contains only the :token:`shape name ` of the error's +:ref:`shape-id`. This can be used to distinguish which specific error has been +serialized in the response. + +.. code-block:: xml + + + + Sender + InvalidGreeting + Hi + setting + + foo-id + + + +------------------------- +Protocol compliance tests +------------------------- + +A full compliance test suite is provided and SHALL be considered a normative +reference: https://github.com/awslabs/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. + +*TODO: Add event stream handling specifications.* -*TODO: Add specifications, protocol examples, etc.* +.. _`RFC 7230 Section 3.3.2`: https://tools.ietf.org/html/rfc7230#section-3.3.2 diff --git a/docs/source/1.0/spec/aws/aws-restxml-protocol.rst b/docs/source/1.0/spec/aws/aws-restxml-protocol.rst index 6b26783c3fb..48f9c09cd1f 100644 --- a/docs/source/1.0/spec/aws/aws-restxml-protocol.rst +++ b/docs/source/1.0/spec/aws/aws-restxml-protocol.rst @@ -331,10 +331,10 @@ as defined in the ``aws.protocols#restXml`` protocol. Operation error serialization ----------------------------- -Error responses in the ``restXml`` protocol are wrapped in an XML element -named ``ErrorResponse`` by default. All error structure members are serialized -within this element, unless bound to another location with HTTP protocol -bindings. +Error responses in the ``restXml`` protocol are wrapped within an XML root +node named ``ErrorResponse`` by default. A nested element, named ``Error``, +contains the serialized error structure members, unless bound to another +location with HTTP protocol bindings. Serialized error shapes MUST also contain an additional child element ``Code`` that contains only the :token:`shape name ` of the error's @@ -354,7 +354,7 @@ serialized in the response. The ``noErrorWrapping`` setting of the ``restXml`` protocol trait disables -using this additional nested XML element. +using this additional nested XML element as the root node. .. code-block:: xml diff --git a/docs/themes/smithy/static/default.css_t b/docs/themes/smithy/static/default.css_t index 7c0035facff..2a17c5176a8 100644 --- a/docs/themes/smithy/static/default.css_t +++ b/docs/themes/smithy/static/default.css_t @@ -538,7 +538,7 @@ table.hlist { code { font-size: 90%; - background-color: #f2f2f2; + background-color: #e9e9e9; } pre { diff --git a/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.protocols.json b/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.protocols.json index 5143148b449..2f06282b5d8 100644 --- a/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.protocols.json +++ b/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.protocols.json @@ -140,10 +140,12 @@ "smithy.api#xmlAttribute", "smithy.api#xmlFlattened", "smithy.api#xmlName", - "smithy.api#xmlNamespace" + "smithy.api#xmlNamespace", + "smithy.api#timestampFormat", + "smithy.api#cors" ] }, - "smithy.api#documentation": "An RPC-based protocol that sends query string requests and XML responses. This protocol does not use HTTP binding traits.", + "smithy.api#documentation": "An RPC-based protocol that sends 'POST' requests in the body as `x-www-form-urlencoded` strings and responses in XML documents. This protocol does not use HTTP binding traits.", "smithy.api#deprecated": {} } }, From 1f28d6f2343d2555a353f7112d8dff55efa4d2e7 Mon Sep 17 00:00:00 2001 From: kstich Date: Tue, 2 Feb 2021 16:32:56 -0800 Subject: [PATCH 2/2] Add documentation for ec2Query This adds documentation for ec2Query by abstracting out the docs for awsQuery and including substitutions for the differences. Examples for awsQuery have been added as well. --- .../1.0/guides/converting-to-openapi.rst | 4 +- .../generating-cloudformation-resources.rst | 4 +- .../1.0/spec/aws/aws-ec2-query-protocol.rst | 259 ++++++++++++ .../1.0/spec/aws/aws-query-protocol.rst | 380 +++++++++--------- .../aws/aws-query-serialization.rst.template | 147 +++++++ .../1.0/spec/aws/aws-restxml-protocol.rst | 80 +--- .../aws/aws-xml-serialization.rst.template | 77 ++++ docs/source/1.0/spec/core/xml-traits.rst | 6 + .../META-INF/smithy/aws.protocols.json | 6 +- 9 files changed, 678 insertions(+), 285 deletions(-) create mode 100644 docs/source/1.0/spec/aws/aws-query-serialization.rst.template create mode 100644 docs/source/1.0/spec/aws/aws-xml-serialization.rst.template diff --git a/docs/source/1.0/guides/converting-to-openapi.rst b/docs/source/1.0/guides/converting-to-openapi.rst index 2d70b3e1073..3897a2906ec 100644 --- a/docs/source/1.0/guides/converting-to-openapi.rst +++ b/docs/source/1.0/guides/converting-to-openapi.rst @@ -111,7 +111,7 @@ specification from a Smithy model using a buildscript dependency: .. code-block:: kotlin :caption: build.gradle.kts - :name: smithy-build-gradle + :name: openapi-smithy-build-gradle plugins { java @@ -1237,7 +1237,7 @@ shows how to install ``software.amazon.smithy:smithy-openapi`` through Gradle: .. code-block:: kotlin :caption: build.gradle.kts - :name: code-build-gradle + :name: openapi-code-build-gradle buildscript { dependencies { diff --git a/docs/source/1.0/guides/generating-cloudformation-resources.rst b/docs/source/1.0/guides/generating-cloudformation-resources.rst index e1af22d8979..a7d1a784d35 100644 --- a/docs/source/1.0/guides/generating-cloudformation-resources.rst +++ b/docs/source/1.0/guides/generating-cloudformation-resources.rst @@ -56,7 +56,7 @@ Resource Schemas from a Smithy model :ref:`using a buildscript dependency .. code-block:: kotlin :caption: build.gradle.kts - :name: smithy-build-gradle + :name: cfn-smithy-build-gradle plugins { java @@ -437,7 +437,7 @@ Gradle: .. code-block:: kotlin :caption: build.gradle.kts - :name: code-build-gradle + :name: cfn-code-build-gradle buildscript { dependencies { diff --git a/docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst b/docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst index e350be85799..62add0a103b 100644 --- a/docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst +++ b/docs/source/1.0/spec/aws/aws-ec2-query-protocol.rst @@ -131,4 +131,263 @@ protocol is: MyStruct.foo=baz +.. _aws.protocols#ec2QueryName-query-key-naming: + +Query key resolution +-------------------- + +The key component used to serialize a member in a request in ``ec2Query`` is +resolved using the following process: + +1. Use the value of the :ref:`aws.protocols#ec2QueryName-trait` applied to the + member, if present. +2. Use the value of the :ref:`xmlName trait ` applied to the + member with the first letter capitalized, if present. +3. Use the default value for the member: + + .. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Member location + - Default value + * - ``list`` member + - The string literal "member" + * - ``set`` member + - The string literal "member" + * - ``map`` key + - The string literal "key" + * - ``map`` value + - The string literal "value" + * - ``structure`` member + - The :token:`member name ` + * - ``union`` member + - The :token:`member name ` + + +---------------- +Supported traits +---------------- + +The ``aws.protocols#ec2Query`` protocol supports the following traits +that affect serialization: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Trait + - Description + * - :ref:`cors ` + - Indicates that the service supports CORS. + * - :ref:`ec2QueryName ` + - By default, the form-urlencoded key segments used in serialized + structures are the same as a structure member name. The ``ec2QueryName`` + changes the key segment name to a custom value. See + :ref:`aws.protocols#ec2QueryName-query-key-naming` for more information. + * - :ref:`xmlAttrubute ` + - Serializes an object property as an XML attribute rather than a nested + XML element. + * - :ref:`xmlFlattened ` + - By default, entries in lists, sets, and maps have values serialized in + nested elements specific to their type. The ``xmlFlattened`` trait + unwraps these elements into the containing structure. + * - :ref:`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 + ``xmlName`` trait changes the these names to a custom value. See + :ref:`aws.protocols#ec2QueryName-query-key-naming` for more information. + * - :ref:`xmlNamespace ` + - Adds an xmlns namespace definition URI to XML element(s) generated + for the targeted shape. + * - :ref:`timestampFormat ` + - Defines a custom timestamp serialization format. + +.. important:: + + This protocol does not support document types. + + +.. |quoted shape name| replace:: ``ec2Query`` +.. |name resolution text| replace:: See :ref:`aws.protocols#ec2QueryName-query-key-naming` + for how to serialize a property using a custom name +.. include:: aws-query-serialization.rst.template + + +Examples +-------- + +.. important:: + + These examples are non-exhaustive. See the :ref:`ec2Query-compliance-tests` + for a suite of compliance tests for the ``ec2Query`` protocol. + + +Structures and Unions +===================== + +|query aggregate text| + +For example, given the following: + +.. code-block:: smithy + + structure Ec2QueryStructuresInput { + foo: String, + + @ec2QueryName("A") + HasQueryName: String, + + @ec2QueryName("B") + @xmlName("IgnoreMe") + HasQueryAndXmlName: String, + + @xmlName("c") + UsesXmlName: String, + + baz: MyStructure, + } + + structure MyStructure { + temp: String, + } + +The ``x-www-form-urlencoded`` serialization is: + +.. code-block:: text + + Action=Ec2QueryStructures + &Version=2020-07-02 + &foo=bar + &A=example0 + &B=example1 + &C=example2 + &baz.temp=example3 + + +Collections +=========== + +|query collection text| + +For example, given the following: + +.. code-block:: smithy + + structure Ec2QueryListsInput { + ListArg: StringList, + + @xmlFlattened + ComplexListArg: GreetingList, + + // Notice that the xmlName on the targeted list member is ignored. + ListArgWithXmlNameMember: ListWithXmlName, + + @ec2QueryName("Hi") + @xmlName("IgnoreMe") + ListArgWithXmlName: ListWithXmlName, + } + + list ListWithXmlName { + @xmlName("item") + member: String + } + + list StringList { + member: String + } + + list GreetingList { + member: GreetingStruct + } + + structure GreetingStruct { + hi: String, + } + +The ``x-www-form-urlencoded`` serialization is: + +.. code-block:: text + + Action=Ec2QueryLists + &Version=2020-07-02 + &ListArg.member.1=foo + &ListArg.member.2=bar + &ListArg.member.3=baz + &ComplexListArg.1.hi=hello + &ComplexListArg.2.hi=hola + &ListArgWithXmlNameMember.1=A + &ListArgWithXmlNameMember.2=B + &Hi.1=A + &Hi.2=B + + +---------------------- +Response serialization +---------------------- + +The ``ec2Query`` 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. + +The value of the ``uri`` member of the :ref:`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``. + +.. code-block:: xml + + + + Hello! + + + +XML shape serialization +----------------------- + +.. include:: aws-xml-serialization.rst.template + + +.. _ec2Query-errors: + +----------------------------- +Operation error serialization +----------------------------- + +Error responses in the ``ec2Query`` protocol are wrapped within an XML root +node named ``Errors``. A nested element, named ``Error``, contains the +serialized error structure members. + +Serialized error shapes MUST also contain an additional child element ``Code`` +that contains only the :token:`shape name ` of the error's +:ref:`shape-id`. This can be used to distinguish which specific error has been +serialized in the response. + +.. code-block:: xml + + + + Sender + InvalidGreeting + Hi + setting + + foo-id + + + +.. _ec2Query-compliance-tests: + +------------------------- +Protocol compliance tests +------------------------- + +A full compliance test suite is provided and SHALL be considered a normative +reference: https://github.com/awslabs/smithy/tree/main/smithy-aws-protocol-tests/model/ec2Query + +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 specifications, protocol examples, etc.* diff --git a/docs/source/1.0/spec/aws/aws-query-protocol.rst b/docs/source/1.0/spec/aws/aws-query-protocol.rst index b3a9425888f..b115dfa6e7f 100644 --- a/docs/source/1.0/spec/aws/aws-query-protocol.rst +++ b/docs/source/1.0/spec/aws/aws-query-protocol.rst @@ -83,7 +83,8 @@ that affect serialization: * - :ref:`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 - ``xmlName`` trait changes the XML element name to a custom value. + ``xmlName`` trait changes these names to a custom value. See + :ref:`aws.protocols#awsQueryName-query-key-naming` for more information. * - :ref:`xmlNamespace ` - Adds an xmlns namespace definition URI to XML element(s) generated for the targeted shape. @@ -95,144 +96,198 @@ that affect serialization: This protocol does not support document types. ------------------ -Protocol Behavior ------------------ +.. |quoted shape name| replace:: ``awsQuery`` +.. |name resolution text| replace:: The :ref:`xmlName-trait` can be used to serialize a property using a custom name +.. include:: aws-query-serialization.rst.template -Every request for the ``awsQuery`` protocol MUST be sent to the -root URL (``/``) using the HTTP "POST" method. +.. _aws.protocols#awsQueryName-query-key-naming: -The ``awsQuery`` protocol does not support custom HTTP bindings. -:ref:`HTTP binding traits ` MUST be ignored if they are present. +Query key resolution +-------------------- -The ``awsQuery`` protocol uses the following headers: +The key component used to serialize a member in a request in ``awsQuery`` is +resolved using the following process: -.. list-table:: - :header-rows: 1 - :widths: 20 20 80 +1. Use the value of the :ref:`xmlName ` trait applied to the + member, if present. +2. Use the default value for the member: - * - Header - - Required - - Description - * - ``Content-Type`` - - true - - This header uses the static values of ``application/x-www-form-urlencoded`` - for requests and ``text/xml`` for responses. - * - ``Content-Length`` - - true - - The standard ``Content-Length`` header defined by - `RFC 7230 Section 3.3.2`_. + .. list-table:: + :header-rows: 1 + :widths: 50 50 + * - Member location + - Default value + * - ``list`` member + - The string literal "member" + * - ``set`` member + - The string literal "member" + * - ``map`` key + - The string literal "key" + * - ``map`` value + - The string literal "value" + * - ``structure`` member + - The :token:`member name ` + * - ``union`` member + - The :token:`member name ` ---------------------- -Request serialization ---------------------- -The ``awsQuery`` protocol serializes inputs in ``x-www-form-urlencoded`` -request bodies. All keys and values MUST be encoded according to :rfc:`3986`. -Requests MUST have the following key value pairs added to the inputs in the -serialized body: +Examples +-------- -.. list-table:: - :header-rows: 1 - :widths: 30 70 +.. important:: - * - Key - - Value - * - ``Action`` - - The name of the operation. - * - ``Version`` - - The value of the :ref:`"version" property of the service `. + These examples are non-exhaustive. See the :ref:`awsQuery-compliance-tests` + for a suite of compliance tests for the ``awsQuery`` protocol. -These, along with other input members, are serialized in the request body, -concatenated with the following rules: -* "&" is used to separate parameter key-value pairs. -* "=" is used to separate parameter names from values. -* "." is used to separate nested parameter name segments. +Structures and Unions +===================== -x-www-form-urlencoded shape serialization ------------------------------------------ +|query aggregate text| -Simple shapes are serialized according to the following rules: +For example, given the following: -.. list-table:: - :header-rows: 1 - :widths: 25 75 - - * - 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. - * - ``timestamp`` - - Text value of the timestamp. This protocol uses ``date-time`` as the - default serialization. However, the :ref:`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. +.. code-block:: smithy -.. list-table:: - :header-rows: 1 - :widths: 25 75 - - * - Smithy type - - Request entity - * - ``list`` - - Each value provided in the list is serialized as a separate key with - a "." separator, ``member``, a "." separator, and a ``1`` indexed - incrementing counter appended to the container's key. The :ref:`xmlName-trait` - can be used to serialize a property using a custom name instead of - ``member``. The :ref:`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. - * - ``set`` - - A set is serialized identically as a ``list`` shape, but only contains - unique values. - * - ``map`` - - Each key and value in each pair provided in the map is serialized as a - separate key with a "." separator, ``entry``, a "." separator, a ``1`` - indexed incrementing counter, a "." separator, and a ``key`` or - ``value`` segment appended to the container's key. The :ref:`xmlName-trait` - can be used to serialize a property using custom names instead of - ``member``, ``key``, or ``value``. The :ref:`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 structure is serialized as a - separate key with a "." separator and the member name appended to the - container's key. The :ref:`xmlName-trait` can be used to serialize a - property using a custom name. - * - ``union`` - - A union is serialized identically as a ``structure`` shape, but only a - single member can be set to a non-null value. + structure QueryStructuresInput { + foo: String, + + @xmlName("Custom") + bar: String, + + baz: MyStructure, + } + + structure MyStructure { + temp: String, + } + +The ``x-www-form-urlencoded`` serialization is: + +.. code-block:: text + + Action=QueryStructures + &Version=2020-07-02 + &foo=example1 + &Custom=example2 + &baz.temp=example3 + + +Collections +=========== + +|query collection text| + +For example, given the following: + +.. code-block:: smithy + + structure QueryListsInput { + ListArg: StringList, + + @xmlFlattened + ComplexListArg: GreetingList, + + // Notice that the xmlName on the targeted list member is ignored. + ListArgWithXmlNameMember: ListWithXmlName, + + @xmlName("Hi") + ListArgWithXmlName: ListWithXmlName, + } + + list ListWithXmlName { + @xmlName("item") + member: String + } + + list StringList { + member: String + } + list GreetingList { + member: GreetingStruct + } + + structure GreetingStruct { + hi: String, + } + +The ``x-www-form-urlencoded`` serialization is: + +.. code-block:: text + + Action=QueryLists + &Version=2020-07-02 + &ListArg.member.1=foo + &ListArg.member.2=bar + &ListArg.member.3=baz + &ComplexListArg.1.hi=hello + &ComplexListArg.2.hi=hola + &ListArgWithXmlNameMember.1=A + &ListArgWithXmlNameMember.2=B + &Hi.1=A + &Hi.2=B + + +Maps +==== + +|query map text| + +For example, given the following: + +.. code-block:: smithy + + 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 + } + +The ``x-www-form-urlencoded`` serialization is: + +.. code-block:: text + + 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 @@ -255,86 +310,10 @@ following is a sample response to an operation named ``XmlTest``. - XML shape serialization ----------------------- -.. list-table:: - :header-rows: 1 - :widths: 25 75 - - * - 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-time`` as the default serialization. However, the - :ref:`timestampFormat ` MAY be used to - customize timestamp serialization. - * - ``document`` - - Undefined. Document shapes are not recommended for use in XML based - protocols. - * - ``list`` - - XML element. Each value provided in the list is serialized as a nested - XML element with the name ``member``. The :ref:`xmlName-trait` can be - used to serialize a property using a custom name. The - :ref:`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. - * - ``set`` - - XML element. A set is serialized identically as a ``list`` shape, - but only contains unique values. - * - ``map`` - - XML element. Each key-value pair provided in the map is serialized in - a nested XML element with the name ``entry`` that contains nested - elements ``key`` and ``value`` for the pair. The :ref:`xmlName-trait` - can be used to serialize key or value properties using a custom name, - it cannot be used to influence the ``entry`` name. The - :ref:`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. - * - ``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 :ref:`xmlName-trait` can be used to - serialize a property using a custom name. The :ref:`xmlAttribute-trait` - can be used to serialize a property in an attribute of the containing - element. - * - ``union`` - - XML element. A union is serialized identically as a ``structure`` - shape, but only a single member can be set to a non-null value. - -.. important:: - - See :ref:`serializing-xml-shapes` for comprehensive documentation, - including examples and behaviors when using multiple XML traits. +.. include:: aws-xml-serialization.rst.template .. _awsQuery-errors: @@ -365,6 +344,8 @@ serialized in the response. +.. _awsQuery-compliance-tests: + ------------------------- Protocol compliance tests ------------------------- @@ -377,4 +358,3 @@ the expected serialized HTTP requests and responses for each case. *TODO: Add event stream handling specifications.* -.. _`RFC 7230 Section 3.3.2`: https://tools.ietf.org/html/rfc7230#section-3.3.2 diff --git a/docs/source/1.0/spec/aws/aws-query-serialization.rst.template b/docs/source/1.0/spec/aws/aws-query-serialization.rst.template new file mode 100644 index 00000000000..c9054164e32 --- /dev/null +++ b/docs/source/1.0/spec/aws/aws-query-serialization.rst.template @@ -0,0 +1,147 @@ +----------------- +Protocol Behavior +----------------- + +Every request for the |quoted shape name| protocol MUST be sent to the +root URL (``/``) using the HTTP "POST" method. + +The |quoted shape name| protocol does not support custom HTTP bindings. +:ref:`HTTP binding traits ` MUST be ignored if they are present. + +The |quoted shape name| protocol uses the following headers: + +.. list-table:: + :header-rows: 1 + :widths: 20 20 80 + + * - Header + - Required + - Description + * - ``Content-Type`` + - true + - This header uses the static values of ``application/x-www-form-urlencoded`` + for requests and ``text/xml`` for responses. + * - ``Content-Length`` + - true + - The standard ``Content-Length`` header defined by + `RFC 7230 Section 3.3.2`_. + + +--------------------- +Request serialization +--------------------- + +The |quoted shape name| protocol serializes inputs in ``x-www-form-urlencoded`` +request bodies. All keys and values MUST be encoded according to :rfc:`3986`. +Requests MUST have the following key value pairs added to the inputs in the +serialized body: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Key + - Value + * - ``Action`` + - The :token:`shape name ` of the operation's :ref:`shape-id`. + * - ``Version`` + - The value of the :ref:`"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: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - 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 ``Foo`` member set to an empty string would be + serialized as "&Foo=". + * - ``timestamp`` + - Text value of the timestamp. This protocol uses ``date-time`` as the + default serialization. However, the :ref:`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. + +.. |query collection text| replace:: + Each value provided in the collection 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. + |name resolution text| instead of "member". The :ref:`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. +.. |query map text| replace:: + 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. |name resolution text| instead of "member", "key", + or "value". The :ref:`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. +.. |query aggregate text| replace:: + 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. + |name resolution text|. Members with null values are not serialized. + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Smithy type + - Request entity + * - ``list`` + - |query collection text| + * - ``set`` + - A set is serialized identically to a ``list`` shape, but only contains + unique values. + * - ``map`` + - |query map text| + * - ``structure`` + - |query aggregate text| + * - ``union`` + - A union is serialized identically to a ``structure`` shape, but only a + single member can be set to a non-null value. + +.. _`RFC 7230 Section 3.3.2`: https://tools.ietf.org/html/rfc7230#section-3.3.2 diff --git a/docs/source/1.0/spec/aws/aws-restxml-protocol.rst b/docs/source/1.0/spec/aws/aws-restxml-protocol.rst index 48f9c09cd1f..7585834fd3b 100644 --- a/docs/source/1.0/spec/aws/aws-restxml-protocol.rst +++ b/docs/source/1.0/spec/aws/aws-restxml-protocol.rst @@ -234,85 +234,7 @@ with the ``httpPayload`` trait: XML shape serialization ----------------------- -XML requests and responses are serialized within an XML root node with the -name of the operation's input, output, or error shape that is being serialized. - -.. list-table:: - :header-rows: 1 - :widths: 25 75 - - * - 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-time`` as the default serialization. However, the - :ref:`timestampFormat ` MAY be used to - customize timestamp serialization. - * - ``document`` - - Undefined. Document shapes are not recommended for use in XML based - protocols. - * - ``list`` - - XML element. Each value provided in the list is serialized as a nested - XML element with the name ``member``. The :ref:`xmlName-trait` can be - used to serialize a property using a custom name. The - :ref:`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. - * - ``set`` - - XML element. A set is serialized identically as a ``list`` shape, - but only contains unique values. - * - ``map`` - - XML element. Each key-value pair provided in the map is serialized in - a nested XML element with the name ``entry`` that contains nested - elements ``key`` and ``value`` for the pair. The :ref:`xmlName-trait` - can be used to serialize key or value properties using a custom name, - it cannot be used to influence the ``entry`` name. The - :ref:`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. - * - ``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 :ref:`xmlName-trait` can be used to - serialize a property using a custom name. The :ref:`xmlAttribute-trait` - can be used to serialize a property in an attribute of the containing - element. - * - ``union`` - - XML element. A union is serialized identically as a ``structure`` - shape, but only a single member can be set to a non-null value. - -.. important:: - - See :ref:`serializing-xml-shapes` for comprehensive documentation, - including examples and behaviors when using multiple XML traits. +.. include:: aws-xml-serialization.rst.template -------------------------- diff --git a/docs/source/1.0/spec/aws/aws-xml-serialization.rst.template b/docs/source/1.0/spec/aws/aws-xml-serialization.rst.template new file mode 100644 index 00000000000..03648d58d78 --- /dev/null +++ b/docs/source/1.0/spec/aws/aws-xml-serialization.rst.template @@ -0,0 +1,77 @@ +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - 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-time`` as the default serialization. However, the + :ref:`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 :ref:`xmlName-trait` can be + used to serialize a property using a custom name. The + :ref:`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 :ref:`xml-list-and-set-serialization` + for more. + * - ``set`` + - XML element. A set is serialized identically to a ``list`` shape, + but only contains unique values. + * - ``map`` + - XML element. Each key-value pair provided in the map is serialized in + a nested XML element with the name ``entry`` that contains nested + elements ``key`` and ``value`` for the pair. The :ref:`xmlName-trait` + can be used to serialize key or value properties using a custom name, + it cannot be used to influence the ``entry`` name. The + :ref:`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 :ref:`xml-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 :ref:`xmlName-trait` can be used to + serialize a property using a custom name. The :ref:`xmlAttribute-trait` + can be used to serialize a property in an attribute of the containing + element. See :ref:`xml-structure-and-union-serialization` for more. + * - ``union`` + - XML element. A union is serialized identically to a ``structure`` + shape, but only a single member can be set to a non-null value. + +.. important:: + + See :ref:`serializing-xml-shapes` for comprehensive documentation, + including examples and behaviors when using multiple XML traits. diff --git a/docs/source/1.0/spec/core/xml-traits.rst b/docs/source/1.0/spec/core/xml-traits.rst index caf540d4432..ca742620d2a 100644 --- a/docs/source/1.0/spec/core/xml-traits.rst +++ b/docs/source/1.0/spec/core/xml-traits.rst @@ -26,6 +26,8 @@ however, protocols MAY choose to deviate from these recommendations if necessary. +.. _xml-structure-and-union-serialization: + Structure and union serialization ================================= @@ -202,6 +204,8 @@ The following table defines how simple types are serialized in XML documents. Document shapes are not recommended for use in XML based protocols. +.. _xml-list-and-set-serialization: + List and set serialization ========================== @@ -369,6 +373,8 @@ The XML serialization of ``Choice`` is: +.. _xml-map-serialization: + Map serialization ================= diff --git a/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.protocols.json b/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.protocols.json index 2f06282b5d8..7fe901fa2ff 100644 --- a/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.protocols.json +++ b/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.protocols.json @@ -162,10 +162,12 @@ "smithy.api#xmlAttribute", "smithy.api#xmlFlattened", "smithy.api#xmlName", - "smithy.api#xmlNamespace" + "smithy.api#xmlNamespace", + "smithy.api#timestampFormat", + "smithy.api#cors" ] }, - "smithy.api#documentation": "An RPC-based protocol that sends Amazon EC2 formatted query string requests and XML responses. This protocol does not use HTTP binding traits.", + "smithy.api#documentation": "An RPC-based protocol that sends 'POST' requests in the body as Amazon EC2 formatted `x-www-form-urlencoded` strings and responses in XML documents. This protocol does not use HTTP binding traits.", "smithy.api#deprecated": {} } },