diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/middlewares/handlers/HttpBodyMiddleware.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/middlewares/handlers/HttpBodyMiddleware.kt index 70ce9d0e9..76e1b467f 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/middlewares/handlers/HttpBodyMiddleware.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/middlewares/handlers/HttpBodyMiddleware.kt @@ -102,7 +102,32 @@ class HttpBodyMiddleware( renderEncodedBodyAddedToRequest(bodyDeclaration, dataDeclaration) } } - ShapeType.DOCUMENT, ShapeType.STRUCTURE, ShapeType.UNION -> { + ShapeType.STRUCTURE, ShapeType.UNION -> { + // delegate to the member encode function + writer.openBlock("do {", "} catch let err {") { + writer.write("let encoder = context.getEncoder()") + writer.openBlock("if let $memberName = input.operationInput.$memberName {", "} else {") { + writer.write("let $dataDeclaration = try encoder.encode(\$L)", memberName) + renderEncodedBodyAddedToRequest(bodyDeclaration, dataDeclaration) + } + writer.indent() + writer.openBlock("if encoder is JSONEncoder {", "} else if encoder is XMLEncoder {") { + writer.write("// Encode an empty body as an empty structure in JSON") + writer.write("let \$L = \"{}\".data(using: .utf8)!", dataDeclaration) + renderEncodedBodyAddedToRequest(bodyDeclaration, dataDeclaration) + } + writer.indent() + writer.write("// Encode an empty body as an empty string in XML") + writer.write("let \$L = \"\".data(using: .utf8)!", dataDeclaration) + renderEncodedBodyAddedToRequest(bodyDeclaration, dataDeclaration) + writer.dedent() + writer.write("}") + writer.dedent() + writer.write("}") + } + renderErrorCase() + } + ShapeType.DOCUMENT -> { writer.openBlock("do {", "} catch let err {") { writer.openBlock("if let $memberName = input.operationInput.$memberName {", "}") { writer.write("let encoder = context.getEncoder()") diff --git a/smithy-swift-codegen/src/test/kotlin/HttpBodyMiddlewareTests.kt b/smithy-swift-codegen/src/test/kotlin/HttpBodyMiddlewareTests.kt index bc1e82114..1ed3db63c 100644 --- a/smithy-swift-codegen/src/test/kotlin/HttpBodyMiddlewareTests.kt +++ b/smithy-swift-codegen/src/test/kotlin/HttpBodyMiddlewareTests.kt @@ -149,11 +149,23 @@ class HttpBodyMiddlewareTests { Self.Context == H.Context { do { + let encoder = context.getEncoder() if let payload1 = input.operationInput.payload1 { - let encoder = context.getEncoder() let payload1data = try encoder.encode(payload1) let payload1body = ClientRuntime.HttpBody.data(payload1data) input.builder.withBody(payload1body) + } else { + if encoder is JSONEncoder { + // Encode an empty body as an empty structure in JSON + let payload1data = "{}".data(using: .utf8)! + let payload1body = ClientRuntime.HttpBody.data(payload1data) + input.builder.withBody(payload1body) + } else if encoder is XMLEncoder { + // Encode an empty body as an empty string in XML + let payload1data = "".data(using: .utf8)! + let payload1body = ClientRuntime.HttpBody.data(payload1data) + input.builder.withBody(payload1body) + } } } catch let err { throw SdkError.client(ClientRuntime.ClientError.serializationFailed(err.localizedDescription))