Skip to content

Commit

Permalink
Add AwsQueryCompatible trait
Browse files Browse the repository at this point in the history
This commit introduces the `aws.protocols#awsQueryCompatible` trait which allows backward compatibility when migrating from awsQuery to awsJson1_0.
  • Loading branch information
AndrewFossAWS committed Sep 19, 2022
1 parent 4504cd0 commit 31ed5a3
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 0 deletions.
46 changes: 46 additions & 0 deletions docs/source-1.0/spec/aws/aws-json.rst.template
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,52 @@ In ``awsJson1_1``, servers SHOULD only send the error's
for both protocols. See `Operation error serialization`_ for full details on how to
deserialize errors for |quoted shape name|.

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

------------------------------------------
``aws.protocols#awsQueryCompatible`` trait
------------------------------------------

Summary
When using the :ref:`awsQuery <aws.protocols#awsQuery-trait>` protocol,
custom ``Code`` and ``HTTP response code`` values can be defined for an error response via
the :ref:`awsQueryError <aws.protocols#awsQueryError-trait>` trait.

The ``awsQueryCompatible`` trait allows services to backward compatibly migrate from ``awsQuery`` to
:ref:`awsJson1_0 <aws.protocols#awsJson1_0-trait>` without removing values defined in the ``awsQueryError`` trait.

This trait adds the ``x-amzn-query-error`` header in the form of ``Code;Fault`` to error responses.
``Code`` is the value defined in the :ref:`awsQueryError <aws.protocols#awsQueryError-trait>`,
and ``Fault`` is one of ``Sender`` or ``Receiver``.

Trait selector
``service [trait|awsJson1_0]``

Value type
Annotation trait

.. code-block:: smithy

$version: "1"
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
}

-------------------------
Protocol compliance tests
Expand Down
46 changes: 46 additions & 0 deletions docs/source-2.0/aws/protocols/aws-json.rst.template
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,52 @@ In ``awsJson1_1``, servers SHOULD only send the error's
for both protocols. See `Operation error serialization`_ for full details on how to
deserialize errors for |quoted shape name|.

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

------------------------------------------
``aws.protocols#awsQueryCompatible`` trait
------------------------------------------

Summary
When using the :ref:`awsQuery <aws.protocols#awsQuery-trait>` protocol,
custom ``Code`` and ``HTTP response code`` values can be defined for an error response via
the :ref:`awsQueryError <aws.protocols#awsQueryError-trait>` trait.

The ``awsQueryCompatible`` trait allows services to backward compatibly migrate from ``awsQuery`` to
:ref:`awsJson1_0 <aws.protocols#awsJson1_0-trait>` without removing values defined in the ``awsQueryError`` trait.

This trait adds the ``x-amzn-query-error`` header in the form of ``Code;Fault`` to error responses.
``Code`` is the value defined in the :ref:`awsQueryError <aws.protocols#awsQueryError-trait>`,
and ``Fault`` is one of ``Sender`` or ``Receiver``.

Trait selector
``service [trait|awsJson1_0]``

Value type
Annotation trait

.. code-block:: smithy

$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
}

-------------------------
Protocol compliance tests
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
$version: "2.0"

namespace aws.protocoltests.json10

use aws.protocols#awsJson1_0
use aws.protocols#awsQueryError
use smithy.test#httpRequestTests
use smithy.test#httpResponseTests

@idempotent
operation GreetingWithError {
input: GreetingWithErrorInput,
output: GreetingWithErrorOutput,
errors: [InvalidGreetingError]
}

@input
structure GreetingWithErrorInput {
greeting: String,
}

@output
structure GreetingWithErrorOutput {
greeting: String,
}

@awsQueryError(
code: "CustomGreetingErrorCode",
httpResponseCode: 402
)
@error("client")
structure InvalidGreetingError {
Message: String,
}

apply InvalidGreeting @httpResponseTests([
{
id: "Json10WithQueryCompatibleGreetingError",
documentation: "@awsQueryCompatible trait is applied to service",
protocol: awsJson1_0,
params: {
Message: "Hi"
},
code: 402,
headers: {
"Content-Type": "application/x-amz-json-1.0",
"x-amzn-query-error": "CustomGreetingErrorCode;Sender"
},
bodyMediaType: "application/json",
body: "{\"__type\": \"InvalidGreetingError\",\"Message\": \"Hi\"}",
appliesTo: "client"
},
])
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
$version: "2.0"

namespace aws.protocoltests.json10

use aws.api#service
use aws.protocols#awsJson1_0
use aws.protocols#awsQueryCompatible
use smithy.test#httpRequestTests
use smithy.test#httpResponseTests


@service(sdkId: "JSON RPC 10 with Query Compatible Trait")
@awsQueryCompatible
@awsJson1_0
service JsonRpc10WithQueryCompatible {
version: "2020-07-14",
operations: [GreetingWithErrors]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.smithy.aws.traits.protocols;

import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.AnnotationTrait;

public final class AwsQueryCompatibleTrait extends AnnotationTrait {

public static final ShapeId ID = ShapeId.from("aws.protocols#awsQueryCompatible");

public AwsQueryCompatibleTrait(ObjectNode node) {
super(ID, node);
}

public AwsQueryCompatibleTrait() {
this(Node.objectNode());
}

public static final class Provider extends AnnotationTrait.Provider<AwsQueryCompatibleTrait> {
public Provider() {
super(ID, AwsQueryCompatibleTrait::new);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ software.amazon.smithy.aws.traits.clientendpointdiscovery.ClientDiscoveredEndpoi
software.amazon.smithy.aws.traits.customizations.S3UnwrappedXmlOutputTrait$Provider
software.amazon.smithy.aws.traits.HttpChecksumTrait$Provider
software.amazon.smithy.aws.traits.protocols.AwsQueryErrorTrait$Provider
software.amazon.smithy.aws.traits.protocols.AwsQueryCompatibleTrait$Provider
software.amazon.smithy.aws.traits.protocols.AwsQueryTrait$Provider
software.amazon.smithy.aws.traits.protocols.Ec2QueryNameTrait$Provider
software.amazon.smithy.aws.traits.protocols.Ec2QueryTrait$Provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ structure awsQueryError {
httpResponseCode: Integer
}

/// Enable backward compatibility when migrating from awsQuery to awsJson protocol
@trait(selector: "service [trait|aws.protocols#awsJson1_0]")
structure awsQueryCompatible {}

/// 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.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
$version: "2.0"

namespace smithy.example

use aws.protocols#awsQueryCompatible
use aws.protocols#awsQueryError
use aws.protocols#awsJson1_0

@awsQueryCompatible
@awsJson1_0
service MyService {
version: "2020-02-05",
errors: [InvalidThingException]
}

@awsQueryError(
code: "InvalidThing",
httpResponseCode: 400,
)
@error("client")
structure InvalidThingException {
message: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[WARNING] smithy.example#MyService: This shape applies a trait that is deprecated: aws.protocols#awsQuery | DeprecatedTrait
[ERROR] smithy.example#MyService: Trait `aws.protocols#awsQueryCompatible` cannot be applied to `smithy.example#MyService`. This trait may only be applied to shapes that match the following selector: service [trait|aws.protocols#awsJson1_0] | TraitTarget
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
$version: "2.0"

namespace smithy.example

use aws.protocols#awsQueryCompatible
use aws.protocols#awsQueryError
use aws.protocols#awsQuery

@awsQueryCompatible
@awsQuery
@xmlNamespace(uri: "https://example.com")
service MyService {
version: "2020-02-05",
errors: [InvalidThingException]
}

@awsQueryError(
code: "InvalidThing",
httpResponseCode: 400,
)
@error("client")
structure InvalidThingException {
message: String
}

0 comments on commit 31ed5a3

Please sign in to comment.