Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default zero value docs #1064

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions docs/source/1.0/guides/evolving-models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,20 @@ Updating structures
The following changes to structure shapes are backward-compatible:

#. Adding new optional members to a structure.
#. Removing the :ref:`required-trait` from a structure member marked with
the :ref:`input-trait`.
#. Removing the :ref:`required-trait` from a structure member when the
structure is marked with the :ref:`input-trait`.
#. Removing the :ref:`required-trait` from a structure member and replacing
it with the :ref:`default-trait`.

The following changes to a structure are not backward-compatible:

#. Renaming a member.
#. Removing a member.
#. Changing the shape targeted by a member.
#. Adding the required trait to a member.
#. Adding the :ref:`required-trait` to a member.
#. Removing the :ref:`default-trait` from a member.
#. Adding the :ref:`default-trait` to a member that was not previously marked
with the :ref:`required-trait`.


Booleans and API evolution
Expand Down Expand Up @@ -95,15 +100,6 @@ The following changes are backward-incompatible:
#. Changing the shape targeted by a union member.


Boxed shapes
============

The :ref:`box-trait` is used to influence code generation in various
programming languages. It is a backward-incompatible change for the ``box``
trait to be added or removed from a shape because it will affect types
generated by tooling that uses Smithy models.


Sparse lists and maps
=====================

Expand Down
45 changes: 45 additions & 0 deletions docs/source/1.0/spec/aws/aws-core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,51 @@ Clients SHOULD use an LRU cache implementation with an initial cache limit of
Clients SHOULD scope the cache globally or to a specific client instance.


.. smithy-trait:: aws.protocols#clientOptional

.. _client-optional-trait:

--------------------------------------
``aws.protocols#clientOptional`` trait
--------------------------------------

Summary
Indicates that a structure member SHOULD be unconditionally generated as
optional, regardless of other traits.
Trait selector
``structure > member``

A member of a structure.
Value type
Annotation trait.

When a member is marked with this trait, non-authoritative tooling like clients
SHOULD treat the member as optional even if the member also has the
:ref:`required-trait` or :ref:`default-trait`. This allows documentation
generators to indicate that a member is required, even if it is not reflected
in the generated code. For example:

.. code-block:: smithy

$version: "2.0"
namespace smithy.example

use aws.api#clientOptional

structure ProductData {
@clientOptional
@required
description: String
}

When generating an AWS SDK client for this shape, the
``ProductData$description`` member SHOULD be generated as an optional member
rather than required.

.. seealso::

:ref:`optionality`

.. smithy-trait:: aws.protocols#httpChecksum
.. _aws.protocols#httpChecksum-trait:

Expand Down
9 changes: 9 additions & 0 deletions docs/source/1.0/spec/aws/aws-default-zero-value.rst.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#. To avoid information disclosure, serializers SHOULD omit the default zero
value of structure members marked with the :ref:`default-trait`.
#. Deserializers MUST tolerate receiving the default zero value of a structure
member marked with the :ref:`default-trait`.
#. Client deserializers MUST fill in a default zero value for structure members
marked with the :ref:`required-trait` that have no serialized value, and the
targeted shape supports zero values. This prevents older clients from
failing to deserialize structures at runtime when the :ref:`required-trait`
is replaced with the :ref:`default-trait`.
11 changes: 8 additions & 3 deletions docs/source/1.0/spec/aws/aws-json.rst.template
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ The |quoted shape name| protocol uses the following headers:
service ``ns.example#MyService`` is ``MyService.MyOp``.


---------------------------
Default value serialization
---------------------------

.. include:: aws-default-zero-value.rst.template


-------------------
Shape serialization
-------------------
Expand Down Expand Up @@ -121,9 +128,7 @@ to convert each shape type:
- 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 :ref:`jsonName-trait` can be used to serialize
a property using a custom name. A null value MAY be provided or
omitted for a :ref:`boxed <box-trait>` member with no observable
difference.
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.
Expand Down
7 changes: 7 additions & 0 deletions docs/source/1.0/spec/aws/aws-query-serialization.rst.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
---------------------------
Default value serialization
---------------------------

.. include:: aws-default-zero-value.rst.template


---------------------
Request serialization
---------------------
Expand Down
11 changes: 8 additions & 3 deletions docs/source/1.0/spec/aws/aws-restjson1-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,13 @@ with the ``httpPayload`` trait:
- ``application/json``


---------------------------
Default value serialization
---------------------------

.. include:: aws-default-zero-value.rst.template


------------------------
JSON shape serialization
------------------------
Expand Down Expand Up @@ -282,9 +289,7 @@ JSON shape serialization
- 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 :ref:`jsonName-trait` can be used to serialize
a property using a custom name. A null value MAY be provided or
omitted for a :ref:`boxed <box-trait>` member with no observable
difference.
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.
Expand Down
7 changes: 7 additions & 0 deletions docs/source/1.0/spec/aws/aws-restxml-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,13 @@ with the ``httpPayload`` trait:
- ``application/xml``


---------------------------
Default value serialization
---------------------------

.. include:: aws-default-zero-value.rst.template


-----------------------
XML shape serialization
-----------------------
Expand Down
1 change: 1 addition & 0 deletions docs/source/1.0/spec/core/constraint-traits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ in a response.
.. seealso::

:ref:`recommended-trait`
:ref:`default-trait`


.. smithy-trait:: smithy.api#uniqueItems
Expand Down
48 changes: 27 additions & 21 deletions docs/source/1.0/spec/core/model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -517,10 +517,8 @@ The following example defines a list with a string member from the
.. rubric:: List member nullability

Lists are considered *dense* by default, meaning they MAY NOT contain ``null``
values. A list MAY be made *sparse* by applying the :ref:`sparse-trait`.
The :ref:`box-trait` is not used to determine if a list is dense or sparse;
a list with no ``@sparse`` trait is always considered dense. The following
example defines a sparse list:
values. A list MAY be made *sparse* by applying the :ref:`sparse-trait`. The
following example defines a sparse list:

.. tabs::

Expand Down Expand Up @@ -675,9 +673,7 @@ across programming languages often do not allow ``null`` keys in maps.

Maps values are considered *dense* by default, meaning they MAY NOT contain
``null`` values. A map MAY be made *sparse* by applying the
:ref:`sparse-trait`. The :ref:`box-trait` is not used to determine if a map
is dense or sparse; a map with no ``@sparse`` trait is always considered
dense. The following example defines a sparse map:
:ref:`sparse-trait`. The following example defines a sparse map:

.. tabs::

Expand Down Expand Up @@ -790,22 +786,32 @@ by ``$``, followed by the member name. For example, the shape ID of the ``foo``
member in the above example is ``smithy.example#MyStructure$foo``.


.. _default-values:
.. _optionality:

Default structure member values
-------------------------------

The values provided for structure members are either always present and set to
a default value when necessary or *boxed*, meaning a value is optionally present
with no default value. Members are considered boxed if the member is marked with
the :ref:`box-trait` or the shape targeted by the member is marked with the box
trait. Members that target strings, timestamps, and aggregate shapes are always
considered boxed and have no default values.
Structure member optionality
----------------------------

- The default value of a ``byte``, ``short``, ``integer``, ``long``,
``float``, and ``double`` shape that is not boxed is zero.
- The default value of a ``boolean`` shape that is not boxed is ``false``.
- All other shapes are always considered boxed and have no default value.
Structure members can use the :ref:`required-trait` and :ref:`default-trait`
to influence the member's optionality, which can have an impact on the code
generated from the model.

Code generated types for structures SHOULD use the
:ref:`default <default-trait>` and :ref:`required <required-trait>` traits to
provide member accessors that always return non-null values.

- When the :ref:`default-trait` is present on a member, the corresponding
accessor SHOULD always return a non-null value by defaulting missing members
with their :ref:`zero values <default-values>`.
- When the :ref:`required-trait` is present on a member, the corresponding
accessor SHOULD always return a non-null value.
- An explicitly provided default zero value and a member that defaults to the
zero value are indistinguishable.
- Because the :ref:`required-trait` can be backward-compatibly removed from
members of structures marked with the :ref:`input-trait` (that is, the input
of an operation), code generators MUST generate code that does not break if
the required trait is removed from these members. For example, this could
mean generating these shapes as a kind of builder pattern or using all
optional members.


.. _union:
Expand Down
Loading