Repository: smithy-lang/smithy
Pull request #2687 (2025-06-27 22:53:31)

Revert "Apply jsonName to examples trait in OpenAPI"
This reverts commit a650eeba413ebb3623f7eac6a2f9317b132f78dc.

Reverting this change that caused some issues to internal packages. We need to revisit the logic.



#### Background
* What do these changes do? 
* Why are they important?

#### Testing
* How did you test these changes?

#### Links
* Links to additional context, if necessary
* Issue #, if applicable (see [here](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) for a list of keywords to use for linking issues)

---
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.



Patch:
diff --git a/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AbstractRestProtocol.java b/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AbstractRestProtocol.java
index a6d2a82ce..dcd550617 100644
--- a/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AbstractRestProtocol.java
+++ b/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AbstractRestProtocol.java
@@ -109,16 +109,11 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
             MessageType messageType
     );
 
-    @Deprecated
-    Node transformSmithyValueToProtocolValue(Node value) {
-        return value;
-    }
-
     /**
      * Converts Smithy values in Node form to a data exchange format used by a protocol (e.g., XML).
      * Then returns the converted value as a long string (escaping where necessary).
      * If data exchange format is JSON (e.g., as in restJson1 protocol),
-     * method should respect the jsonName trait, but otherwise not modify the node.
+     * method should return values without any modification.
      *
      * <p> Used for the value property of OpenAPI example objects.
      * For protocols that do not use JSON as data-exchange format,
@@ -127,14 +122,10 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
      * E.g., for restXML protocol, values would be converted to a large String of XML value / object,
      * escaping where necessary.
      *
-     * @param context Conversion context.
-     * @param shape The shape that the value represents.
-     * @param value value to be converted.
+     * @param value    value to be converted.
      * @return  the long string (escaped where necessary) of values in a data exchange format used by a protocol.
      */
-    Node transformSmithyValueToProtocolValue(Context<T> context, Shape shape, Node value) {
-        return value;
-    }
+    abstract Node transformSmithyValueToProtocolValue(Node value);
 
     @Override
     public Set<String> getProtocolRequestHeaders(Context<T> context, OperationShape operationShape) {
@@ -213,7 +204,6 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
                     .in("path")
                     .schema(schema)
                     .examples(createExamplesForMembersWithHttpTraits(
-                            context,
                             operation,
                             binding,
                             MessageType.REQUEST,
@@ -229,7 +219,6 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
      * path parameters, query parameters, header parameters, and payload.
      */
     private Map<String, Node> createExamplesForMembersWithHttpTraits(
-            Context<T> context,
             Shape operationOrError,
             HttpBinding binding,
             MessageType type,
@@ -240,17 +229,15 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
         }
 
         if (type == MessageType.ERROR) {
-            return createErrorExamplesForMembersWithHttpTraits(context, operationOrError, binding, operation);
+            return createErrorExamplesForMembersWithHttpTraits(operationOrError, binding, operation);
         } else {
             Map<String, Node> examples = new TreeMap<>();
             // unique numbering for unique example names in OpenAPI.
             int uniqueNum = 1;
 
-            List<ExamplesTrait.Example> modeledExamples = operationOrError.getTrait(ExamplesTrait.class)
-                    .map(ExamplesTrait::getExamples)
-                    .orElse(Collections.emptyList());
-
-            for (ExamplesTrait.Example example : modeledExamples) {
+            Optional<ExamplesTrait> examplesTrait = operationOrError.getTrait(ExamplesTrait.class);
+            for (ExamplesTrait.Example example : examplesTrait.map(ExamplesTrait::getExamples)
+                    .orElse(Collections.emptyList())) {
                 ObjectNode inputOrOutput = type == MessageType.REQUEST ? example.getInput()
                         : example.getOutput().orElse(Node.objectNode());
                 String name = operationOrError.getId().getName() + "_example" + uniqueNum++;
@@ -264,7 +251,7 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
                             ExampleObject.builder()
                                     .summary(example.getTitle())
                                     .description(example.getDocumentation().orElse(""))
-                                    .value(transformSmithyValueToProtocolValue(context, binding.getMember(), values))
+                                    .value(transformSmithyValueToProtocolValue(values))
                                     .build()
                                     .toNode());
                 }
@@ -277,7 +264,6 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
      * Helper method for createExamples() method.
      */
     private Map<String, Node> createErrorExamplesForMembersWithHttpTraits(
-            Context<T> context,
             Shape error,
             HttpBinding binding,
             OperationShape operation
@@ -304,7 +290,7 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
                         ExampleObject.builder()
                                 .summary(example.getTitle())
                                 .description(example.getDocumentation().orElse(""))
-                                .value(transformSmithyValueToProtocolValue(context, binding.getMember(), values))
+                                .value(transformSmithyValueToProtocolValue(values))
                                 .build()
                                 .toNode());
             }
@@ -316,7 +302,6 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
      * This method is used for converting the Smithy examples to OpenAPI examples for non-payload HTTP message body.
      */
     private Map<String, Node> createBodyExamples(
-            Context<T> context,
             Shape operationOrError,
             List<HttpBinding> bindings,
             MessageType type,
@@ -327,7 +312,7 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
         }
 
         if (type == MessageType.ERROR) {
-            return createErrorBodyExamples(context, operationOrError, bindings, operation);
+            return createErrorBodyExamples(operationOrError, bindings, operation);
         } else {
             Map<String, Node> examples = new TreeMap<>();
             // unique numbering for unique example names in OpenAPI.
@@ -336,30 +321,18 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
             Optional<ExamplesTrait> examplesTrait = operationOrError.getTrait(ExamplesTrait.class);
             for (ExamplesTrait.Example example : examplesTrait.map(ExamplesTrait::getExamples)
                     .orElse(Collections.emptyList())) {
-
-                Shape structure = operationOrError;
-                if (operationOrError.isOperationShape()) {
-                    OperationShape op = operationOrError.asOperationShape().get();
-                    if (type == MessageType.REQUEST) {
-                        structure = context.getModel().expectShape(op.getInputShape());
-                    } else {
-                        structure = context.getModel().expectShape(op.getOutputShape());
-                    }
-                }
-
                 // get members included in bindings
                 ObjectNode values = getMembersWithHttpBindingTrait(bindings,
                         type == MessageType.REQUEST ? example.getInput()
                                 : example.getOutput().orElse(Node.objectNode()));
                 String name = operationOrError.getId().getName() + "_example" + uniqueNum++;
-
                 // this if condition is needed to avoid errors when converting examples of response.
                 if (!example.getError().isPresent() || type == MessageType.REQUEST) {
                     examples.put(name,
                             ExampleObject.builder()
                                     .summary(example.getTitle())
                                     .description(example.getDocumentation().orElse(""))
-                                    .value(transformSmithyValueToProtocolValue(context, structure, values))
+                                    .value(transformSmithyValueToProtocolValue(values))
                                     .build()
                                     .toNode());
                 }
@@ -369,7 +342,6 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
     }
 
     private Map<String, Node> createErrorBodyExamples(
-            Context<T> context,
             Shape error,
             List<HttpBinding> bindings,
             OperationShape operation
@@ -390,7 +362,7 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
                         ExampleObject.builder()
                                 .summary(example.getTitle())
                                 .description(example.getDocumentation().orElse(""))
-                                .value(transformSmithyValueToProtocolValue(context, error, values))
+                                .value(transformSmithyValueToProtocolValue(values))
                                 .build()
                                 .toNode());
             }
@@ -484,8 +456,7 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
             }
 
             param.schema(createQuerySchema(context, member, target));
-            param.examples(
-                    createExamplesForMembersWithHttpTraits(context, operation, binding, MessageType.REQUEST, null));
+            param.examples(createExamplesForMembersWithHttpTraits(operation, binding, MessageType.REQUEST, null));
             result.add(param.build());
         }
 
@@ -525,8 +496,7 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
                 param.in(null).name(null);
             }
 
-            param.examples(
-                    createExamplesForMembersWithHttpTraits(context, operationOrError, binding, messageType, operation));
+            param.examples(createExamplesForMembersWithHttpTraits(operationOrError, binding, messageType, operation));
 
             // Create the appropriate schema based on the shape type.
             Shape target = context.getModel().expectShape(member.getTarget());
@@ -596,7 +566,6 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
             return shapeName + "InputPayload";
         }).toBuilder()
                 .examples(createExamplesForMembersWithHttpTraits(
-                        context,
                         operation,
                         binding,
                         MessageType.REQUEST,
@@ -629,7 +598,7 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
         String pointer = context.putSynthesizedSchema(synthesizedName, schema);
         MediaTypeObject mediaTypeObject = MediaTypeObject.builder()
                 .schema(Schema.builder().ref(pointer).build())
-                .examples(createBodyExamples(context, operation, bindings, MessageType.REQUEST, null))
+                .examples(createBodyExamples(operation, bindings, MessageType.REQUEST, null))
                 .build();
 
         // If any of the top level bindings are required, then the body itself must be required.
@@ -788,7 +757,6 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
                     : shapeName + "ErrorPayload";
         }).toBuilder()
                 .examples(createExamplesForMembersWithHttpTraits(
-                        context,
                         operationOrError,
                         binding,
                         type,
@@ -872,7 +840,7 @@ abstract class AbstractRestProtocol<T extends Trait> implements OpenApiProtocol<
         String pointer = context.putSynthesizedSchema(synthesizedName, schema);
         MediaTypeObject mediaTypeObject = MediaTypeObject.builder()
                 .schema(Schema.builder().ref(pointer).build())
-                .examples(createBodyExamples(context, operationOrError, bindings, messageType, operation))
+                .examples(createBodyExamples(operationOrError, bindings, messageType, operation))
                 .build();
 
         responseBuilder.putContent(mediaType, mediaTypeObject);
diff --git a/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AwsRestJson1Protocol.java b/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AwsRestJson1Protocol.java
index 3f84277ac..bbde5e404 100644
--- a/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AwsRestJson1Protocol.java
+++ b/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AwsRestJson1Protocol.java
@@ -166,7 +166,7 @@ public final class AwsRestJson1Protocol extends AbstractRestProtocol<RestJson1Tr
     }
 
     @Override
-    Node transformSmithyValueToProtocolValue(Context<RestJson1Trait> context, Shape shape, Node value) {
-        return value.accept(new JsonValueNodeTransformer(context, shape));
+    Node transformSmithyValueToProtocolValue(Node value) {
+        return value;
     }
 }
diff --git a/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/JsonValueNodeTransformer.java b/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/JsonValueNodeTransformer.java
deleted file mode 100644
index 62f4df56e..000000000
--- a/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/JsonValueNodeTransformer.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0
- */
-package software.amazon.smithy.openapi.fromsmithy.protocols;
-
-import java.util.Map;
-import software.amazon.smithy.model.node.ArrayNode;
-import software.amazon.smithy.model.node.BooleanNode;
-import software.amazon.smithy.model.node.Node;
-import software.amazon.smithy.model.node.NodeVisitor;
-import software.amazon.smithy.model.node.NullNode;
-import software.amazon.smithy.model.node.NumberNode;
-import software.amazon.smithy.model.node.ObjectNode;
-import software.amazon.smithy.model.node.StringNode;
-import software.amazon.smithy.model.shapes.MapShape;
-import software.amazon.smithy.model.shapes.MemberShape;
-import software.amazon.smithy.model.shapes.Shape;
-import software.amazon.smithy.model.traits.JsonNameTrait;
-import software.amazon.smithy.openapi.fromsmithy.Context;
-
-/**
- * Applies the jsonName trait to a node value if applicable.
- */
-public class JsonValueNodeTransformer implements NodeVisitor<Node> {
-    private final Context<?> context;
-    private final Shape shape;
-
-    /**
-     * Construct a JsonValueNodeTransformer.
-     *
-     * @param context Conversion context. Used to determine if jsonName should be used.
-     * @param shape The shape of the node being converted.
-     */
-    public JsonValueNodeTransformer(Context<?> context, Shape shape) {
-        this.context = context;
-        this.shape = shape;
-    }
-
-    @Override
-    public Node booleanNode(BooleanNode node) {
-        return node;
-    }
-
-    @Override
-    public Node nullNode(NullNode node) {
-        return node;
-    }
-
-    @Override
-    public Node numberNode(NumberNode node) {
-        return node;
-    }
-
-    @Override
-    public Node stringNode(StringNode node) {
-        return node;
-    }
-
-    @Override
-    public Node arrayNode(ArrayNode node) {
-        ArrayNode.Builder resultBuilder = ArrayNode.builder();
-        Shape listShape = shape.asMemberShape()
-                .map(m -> context.getModel().expectShape(m.getTarget()))
-                .orElse(shape);
-
-        Shape target = context.getModel().expectShape(listShape.asListShape().get().getMember().getTarget());
-        JsonValueNodeTransformer elementTransformer = new JsonValueNodeTransformer(context, target);
-        for (Node element : node.getElements()) {
-            resultBuilder.withValue(element.accept(elementTransformer));
-        }
-        return resultBuilder.build();
-    }
-
-    @Override
-    public Node objectNode(ObjectNode node) {
-        Shape actual = shape.asMemberShape()
-                .map(m -> context.getModel().expectShape(m.getTarget()))
-                .orElse(shape);
-
-        if (shape.isMapShape()) {
-            return mapNode(actual.asMapShape().get(), node);
-        }
-        return structuredNode(actual, node);
-    }
-
-    private Node structuredNode(Shape structure, ObjectNode node) {
-        ObjectNode.Builder resultBuilder = ObjectNode.builder();
-        for (Map.Entry<StringNode, Node> entry : node.getMembers().entrySet()) {
-            String key = entry.getKey().getValue();
-            if (structure.getMember(key).isPresent()) {
-                MemberShape member = structure.getMember(key).get();
-                Shape target = context.getModel().expectShape(member.getTarget());
-                JsonValueNodeTransformer entryTransformer = new JsonValueNodeTransformer(context, target);
-                resultBuilder.withMember(getKey(member), entry.getValue().accept(entryTransformer));
-            } else {
-                resultBuilder.withMember(key, entry.getValue());
-            }
-        }
-        return resultBuilder.build();
-    }
-
-    private String getKey(MemberShape member) {
-        if (!context.getJsonSchemaConverter().getConfig().getUseJsonName()) {
-            return member.getMemberName();
-        }
-        return member.getTrait(JsonNameTrait.class)
-                .map(JsonNameTrait::getValue)
-                .orElse(member.getMemberName());
-    }
-
-    private Node mapNode(MapShape map, ObjectNode node) {
-        ObjectNode.Builder resultBuilder = ObjectNode.builder();
-        Shape target = context.getModel().expectShape(map.getValue().getTarget());
-        JsonValueNodeTransformer entryTransformer = new JsonValueNodeTransformer(context, target);
-        for (Map.Entry<StringNode, Node> entry : node.getMembers().entrySet()) {
-            resultBuilder.withMember(entry.getKey(), entry.getValue().accept(entryTransformer));
-        }
-        return resultBuilder.build();
-    }
-}


Test patch:
diff --git a/smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.openapi.json b/smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.openapi.json
index 9d4d7413f..4e2350e58 100644
--- a/smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.openapi.json
+++ b/smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.openapi.json
@@ -149,7 +149,7 @@
                     "description": "withdrawTestDoc",
                     "value": {
                       "location": "Denver",
-                      "bank": "Chase",
+                      "bankName": "Chase",
                       "atmRecording": "dGVzdHZpZGVv"
                     }
                   }
@@ -470,7 +470,7 @@
           "location": {
             "type": "string"
           },
-          "bank": {
+          "bankName": {
             "type": "string"
           },
           "atmRecording": {
diff --git a/smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.smithy b/smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.smithy
index 5bd61b88a..b32459f4b 100644
--- a/smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.smithy
+++ b/smithy-openapi/src/test/resources/software/amazon/smithy/openapi/fromsmithy/protocols/examples-test.smithy
@@ -1,92 +1,59 @@
-$version: "2"
-
 namespace smithy.examplestrait
 
 use aws.protocols#restJson1
 
 @restJson1
 service Banking {
-    version: "2022-06-26"
-    operations: [
-        Deposit
-        Withdraw
-    ]
+    version: "2022-06-26",
+    operations: [Deposit, Withdraw]
 }
 
 @idempotent
 @http(method: "PUT", uri: "/account/{username}", code: 200)
 operation Deposit {
-    input := {
-        @httpHeader("accountNumber")
-        accountNumber: String
-
-        @required
-        @httpLabel
-        username: String
-
-        @httpQuery("accountHistory")
-        accountHistory: ExampleList
-
-        @httpPayload
-        depositAmount: String
-    }
-
-    output := {
-        @httpHeader("username")
-        username: String
-
-        @httpHeader("authenticationResult")
-        authenticationResult: ExampleList
-
-        textMessage: String
-
-        emailMessage: String
-    }
-
-    errors: [
-        InvalidUsername
-        InvalidAmount
-    ]
+    input: DepositInput,
+    output: DepositOutput,
+    errors: [InvalidUsername, InvalidAmount]
 }
 
 @idempotent
 @http(method: "PATCH", uri: "/account/withdraw", code: 200)
 operation Withdraw {
-    input := {
-        @httpHeader("accountNumber")
-        accountNumber: String
-
-        @httpHeader("username")
-        username: String
-
-        @httpQueryParams
-        withdrawParams: ExampleMap
-
-        time: date
+    input: WithdrawInput,
+    output: WithdrawOutput,
+    errors: [InvalidUsername]
+}
 
-        withdrawAmount: String
+@input
+structure DepositInput {
+    @httpHeader("accountNumber")
+    accountNumber: String,
 
-        withdrawOption: String
-    }
+    @required
+    @httpLabel
+    username: String,
 
-    output := {
-        @httpHeader("branch")
-        branch: String
+    @httpQuery("accountHistory")
+    accountHistory: ExampleList,
 
-        @httpHeader("result")
-        accountHistory: ExampleList
+    @httpPayload
+    depositAmount: String
+}
 
-        location: String
+@input
+structure WithdrawInput {
+    @httpHeader("accountNumber")
+    accountNumber: String,
 
-        @jsonName("bank")
-        bankName: String
+    @httpHeader("username")
+    username: String,
 
-        atmRecording: exampleVideo
-    }
+    @httpQueryParams()
+    withdrawParams: ExampleMap,
 
-    errors: [
-        InvalidUsername
-    ]
+    time: date,
+    withdrawAmount: String,
+    withdrawOption: String
 }
 
 list ExampleList {
@@ -94,7 +61,7 @@ list ExampleList {
 }
 
 map ExampleMap {
-    key: String
+    key: String,
     value: String
 }
 
@@ -104,10 +71,35 @@ blob exampleVideo
 @timestampFormat("http-date")
 timestamp date
 
+@output
+structure DepositOutput {
+    @httpHeader("username")
+    username: String,
+
+    @httpHeader("authenticationResult")
+    authenticationResult: ExampleList,
+
+    textMessage: String,
+    emailMessage: String
+}
+
+@output
+structure WithdrawOutput {
+    @httpHeader("branch")
+    branch: String,
+
+    @httpHeader("result")
+    accountHistory: ExampleList,
+
+    location: String,
+    bankName: String,
+    atmRecording: exampleVideo
+}
+
 @error("client")
 structure InvalidUsername {
     @httpHeader("internalErrorCode")
-    internalErrorCode: String
+    internalErrorCode: String,
 
     @httpPayload
     errorMessage: String
@@ -115,90 +107,107 @@ structure InvalidUsername {
 
 @error("server")
 structure InvalidAmount {
-    errorMessage1: String
-    errorMessage2: String
+    errorMessage1: String,
+    errorMessage2: String,
     errorMessage3: String
 }
 
-apply Deposit @examples([
-    {
-        title: "Deposit valid example"
-        documentation: "depositTestDoc"
-        input: {
-            accountNumber: "102935"
-            username: "sichanyoo"
-            accountHistory: ["10", "-25", "50"]
-            depositAmount: "200"
-        }
-        output: {
-            username: "sichanyoo"
-            authenticationResult: ["pass1", "pass2", "pass3"]
-            textMessage: "You deposited 200-text"
-            emailMessage: "You deposited 200-email"
+apply Deposit @examples(
+    [
+        {
+            title: "Deposit valid example",
+            documentation: "depositTestDoc",
+            input: {
+                accountNumber: "102935",
+                username: "sichanyoo",
+                accountHistory: ["10", "-25", "50"],
+                depositAmount: "200"
+            },
+            output: {
+                username: "sichanyoo",
+                authenticationResult: ["pass1", "pass2", "pass3"],
+                textMessage: "You deposited 200-text",
+                emailMessage: "You deposited 200-email"
+            },
+        },
+
+        {
+            title: "Deposit invalid username example",
+            documentation: "depositTestDoc2",
+            input: {
+                username: "sichanyoo",
+                accountHistory: ["-200", "200", "10"],
+                depositAmount: "-200"
+            },
+            error: {
+                shapeId: InvalidUsername,
+                content: {
+                    internalErrorCode: "4gsw2-34",
+                    errorMessage: "ERROR: Invalid username."
+                }
+            },
+        },
+
+        {
+            title: "Deposit invalid amount example",
+            documentation: "depositTestDoc3",
+            input: {
+                accountNumber: "203952",
+                username: "obidos",
+                accountHistory: ["2000", "50000", "100"],
+                depositAmount: "-100"
+            },
+            error: {
+                shapeId: InvalidAmount,
+                content: {
+                    errorMessage1: "ERROR: Invalid amount.",
+                    errorMessage2: "2gdx4-34",
+                    errorMessage3: "2gcbe-98"
+                }
+            },
         }
-    }
-    {
-        title: "Deposit invalid username example"
-        documentation: "depositTestDoc2"
-        input: {
-            username: "sichanyoo"
-            accountHistory: ["-200", "200", "10"]
-            depositAmount: "-200"
-        }
-        error: {
-            shapeId: InvalidUsername
-            content: { internalErrorCode: "4gsw2-34", errorMessage: "ERROR: Invalid username." }
-        }
-    }
-    {
-        title: "Deposit invalid amount example"
-        documentation: "depositTestDoc3"
-        input: {
-            accountNumber: "203952"
-            username: "obidos"
-            accountHistory: ["2000", "50000", "100"]
-            depositAmount: "-100"
-        }
-        error: {
-            shapeId: InvalidAmount
-            content: { errorMessage1: "ERROR: Invalid amount.", errorMessage2: "2gdx4-34", errorMessage3: "2gcbe-98" }
-        }
-    }
-])
-
-apply Withdraw @examples([
-    {
-        title: "Withdraw valid example"
-        documentation: "withdrawTestDoc"
-        input: {
-            accountNumber: "124634"
-            username: "amazon"
-            withdrawParams: { location: "Denver", bankName: "Chase" }
-            time: "Tue, 29 Apr 2014 18:30:38 GMT"
-            withdrawAmount: "-35"
-            withdrawOption: "ATM"
-        }
-        output: {
-            branch: "Denver-203"
-            accountHistory: ["34", "5", "-250"]
-            location: "Denver"
-            bankName: "Chase"
-            atmRecording: "dGVzdHZpZGVv"
-        }
-    }
-    {
-        title: "Withdraw invalid username example"
-        documentation: "withdrawTestDoc2"
-        input: {
-            accountNumber: "231565"
-            username: "peccy"
-            withdrawParams: { location: "Seoul", bankName: "Chase" }
-            withdrawAmount: "-450"
-            withdrawOption: "Venmo"
-        }
-        error: {
-            shapeId: InvalidUsername
-            content: { internalErrorCode: "8dfws-21", errorMessage: "ERROR: Invalid username." }
+    ]
+)
+
+apply Withdraw @examples(
+    [
+        {
+            title: "Withdraw valid example",
+            documentation: "withdrawTestDoc",
+            input: {
+                accountNumber: "124634",
+                username: "amazon",
+                withdrawParams: {"location" : "Denver", "bankName" : "Chase"},
+                time: "Tue, 29 Apr 2014 18:30:38 GMT",
+                withdrawAmount: "-35",
+                withdrawOption: "ATM"
+            },
+            output: {
+                branch: "Denver-203",
+                accountHistory: ["34", "5", "-250"],
+                location: "Denver",
+                bankName: "Chase",
+                atmRecording: "dGVzdHZpZGVv"
+            },
+        },
+
+        {
+            title: "Withdraw invalid username example",
+            documentation: "withdrawTestDoc2",
+            input: {
+                accountNumber: "231565",
+                username: "peccy",
+                withdrawParams: {"location" : "Seoul", "bankName" : "Chase"},
+                withdrawAmount: "-450",
+                withdrawOption: "Venmo"
+            },
+            error: {
+                shapeId: InvalidUsername,
+                content: {
+                    internalErrorCode: "8dfws-21",
+                    errorMessage: "ERROR: Invalid username."
+                }
+            },
         }
-    }
-])
+    ]
+)