diff --git a/Sources/AWSLambdaEvents/APIGateway+Encodable.swift b/Sources/AWSLambdaEvents/APIGateway+Encodable.swift new file mode 100644 index 0000000..b9d7893 --- /dev/null +++ b/Sources/AWSLambdaEvents/APIGateway+Encodable.swift @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftAWSLambdaRuntime open source project +// +// Copyright (c) 2017-2022 Apple Inc. and the SwiftAWSLambdaRuntime project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import HTTPTypes + +#if canImport(FoundationEssentials) +import class FoundationEssentials.JSONEncoder +import struct FoundationEssentials.Data +#else +import class Foundation.JSONEncoder +import struct Foundation.Data +#endif + +extension Encodable { + fileprivate func string() throws -> String { + let encoded = try JSONEncoder().encode(self) + return String(decoding: encoded, as: UTF8.self) + } +} + +extension APIGatewayResponse { + + public init( + statusCode: HTTPResponse.Status, + headers: HTTPHeaders? = nil, + multiValueHeaders: HTTPMultiValueHeaders? = nil, + encodableBody: Input + ) throws { + self.init( + statusCode: statusCode, + headers: headers, + multiValueHeaders: multiValueHeaders, + body: try encodableBody.string(), + isBase64Encoded: nil + ) + } +} + +extension APIGatewayV2Response { + + public init( + statusCode: HTTPResponse.Status, + headers: HTTPHeaders? = nil, + encodableBody: Input, + cookies: [String]? = nil + ) throws { + self.init( + statusCode: statusCode, + headers: headers, + body: try encodableBody.string(), + isBase64Encoded: nil, + cookies: cookies + ) + } +} diff --git a/Tests/AWSLambdaEventsTests/APIGateway+EncodableTests.swift b/Tests/AWSLambdaEventsTests/APIGateway+EncodableTests.swift new file mode 100644 index 0000000..02025b4 --- /dev/null +++ b/Tests/AWSLambdaEventsTests/APIGateway+EncodableTests.swift @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftAWSLambdaRuntime open source project +// +// Copyright (c) 2017-2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Foundation +import Testing + +@testable import AWSLambdaEvents + +struct APIGatewayEncodableResponseTests { + + // MARK: Encoding + struct BusinessResponse: Codable, Equatable { + let message: String + let code: Int + } + + @Test + func testResponseEncodingV2() throws { + + // given + let businessResponse = BusinessResponse(message: "Hello World", code: 200) + + var response: APIGatewayV2Response? = nil + #expect(throws: Never.self) { + try response = APIGatewayV2Response(statusCode: .ok, encodableBody: businessResponse) + } + try #require(response?.body != nil) + + // when + let body = response?.body?.data(using: .utf8) + try #require(body != nil) + + #expect(throws: Never.self) { + let encodedBody = try JSONDecoder().decode(BusinessResponse.self, from: body!) + + // then + #expect(encodedBody == businessResponse) + } + } + + @Test + func testResponseEncoding() throws { + + // given + let businessResponse = BusinessResponse(message: "Hello World", code: 200) + + var response: APIGatewayResponse? = nil + #expect(throws: Never.self) { + try response = APIGatewayResponse(statusCode: .ok, encodableBody: businessResponse) + } + try #require(response?.body != nil) + + // when + let body = response?.body?.data(using: .utf8) + try #require(body != nil) + + #expect(throws: Never.self) { + let encodedBody = try JSONDecoder().decode(BusinessResponse.self, from: body!) + + // then + #expect(encodedBody == businessResponse) + } + } +}