Skip to content

Commit 7a826d4

Browse files
committed
Add body type cast for APIGateway.Request
1 parent 1b76ad9 commit 7a826d4

File tree

6 files changed

+263
-134
lines changed

6 files changed

+263
-134
lines changed

Examples/CloudFunctions/Sources/APIGateway/main.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ SCF.run(APIGatewayProxySCF())
3737

3838
// FIXME: Use proper Event abstractions once added to TencentSCFRuntime
3939
struct APIGatewayProxySCF: EventLoopSCFHandler {
40-
public typealias In = APIGateway.Request
40+
public typealias In = APIGateway.Request<String>
4141
public typealias Out = APIGateway.Response
4242

43-
public func handle(context: SCF.Context, event: APIGateway.Request) -> EventLoopFuture<APIGateway.Response> {
43+
public func handle(context: SCF.Context, event: APIGateway.Request<String>) -> EventLoopFuture<APIGateway.Response> {
4444
context.logger.debug("hello, api gateway!")
4545
return context.eventLoop.makeSucceededFuture(APIGateway.Response(statusCode: .ok, body: "Hello, world!"))
4646
}

Sources/TencentSCFEvents/APIGateway.swift

Lines changed: 0 additions & 128 deletions
This file was deleted.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===------------------------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftTencentSCFRuntime open source project
4+
//
5+
// Copyright (c) 2020 stevapple and the SwiftTencentSCFRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftTencentSCFRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===------------------------------------------------------------------------------------===//
14+
15+
import class Foundation.JSONDecoder
16+
import class Foundation.JSONEncoder
17+
18+
// https://cloud.tencent.com/document/product/583/12513
19+
20+
public enum APIGateway {
21+
/// `APIGateway.Request` contains data coming from the API Gateway.
22+
public struct Request<T: Decodable> {
23+
public struct Context: Codable {
24+
public let identity: [String: String]
25+
public let serviceId: String
26+
public let path: String
27+
public let sourceIp: String
28+
public let stage: Stage
29+
public let httpMethod: HTTPMethod
30+
}
31+
32+
public let path: String
33+
public let httpMethod: HTTPMethod
34+
public let headers: HTTPHeaders
35+
public let query: [String: String]
36+
37+
public let pathParameters: [String: String]
38+
public let queryStringParameters: [String: String]
39+
public let headerParameters: [String: String]
40+
41+
public let context: Context
42+
public let body: T?
43+
}
44+
45+
public enum Stage: String, Codable {
46+
case test
47+
case debug
48+
case prepub
49+
case release
50+
}
51+
52+
/// `APIGateway.Response` stores response ready for sending to the API Gateway.
53+
public struct Response: Codable {
54+
public let statusCode: HTTPResponseStatus
55+
public let headers: HTTPHeaders
56+
public let body: String
57+
public let isBase64Encoded: Bool
58+
}
59+
}
60+
61+
internal extension APIGateway {
62+
static let defaultJSONDecoder = JSONDecoder()
63+
static let defaultJSONEncoder = JSONEncoder()
64+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===------------------------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftTencentSCFRuntime open source project
4+
//
5+
// Copyright (c) 2020 stevapple and the SwiftTencentSCFRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftTencentSCFRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===------------------------------------------------------------------------------------===//
14+
15+
// https://cloud.tencent.com/document/product/583/12513
16+
17+
extension APIGateway.Request: Decodable {
18+
enum CodingKeys: String, CodingKey {
19+
case context = "requestContext"
20+
case body
21+
case headers
22+
case query = "queryString"
23+
case path
24+
case httpMethod
25+
26+
case pathParameters
27+
case queryStringParameters
28+
case headerParameters
29+
}
30+
31+
public init(from decoder: Decoder) throws {
32+
let container = try decoder.container(keyedBy: CodingKeys.self)
33+
34+
context = try container.decode(Context.self, forKey: .context)
35+
headers = try container.decode(HTTPHeaders.self, forKey: .headers)
36+
path = try container.decode(String.self, forKey: .path)
37+
httpMethod = try container.decode(HTTPMethod.self, forKey: .httpMethod)
38+
query = try container.decode([String: String].self, forKey: .query)
39+
pathParameters = try container.decode([String: String].self, forKey: .pathParameters)
40+
queryStringParameters = try container.decode([String: String].self, forKey: .queryStringParameters)
41+
headerParameters = try container.decode([String: String].self, forKey: .headerParameters)
42+
43+
do {
44+
body = try container.decodeIfPresent(T.self, forKey: .body)
45+
} catch {
46+
let bodyJson = try container.decodeIfPresent(String.self, forKey: .body)
47+
if let data = bodyJson?.data(using: .utf8) {
48+
body = try APIGateway.defaultJSONDecoder.decode(T.self, from: data)
49+
} else {
50+
body = nil
51+
}
52+
}
53+
}
54+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===------------------------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftTencentSCFRuntime open source project
4+
//
5+
// Copyright (c) 2020 stevapple and the SwiftTencentSCFRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftTencentSCFRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===------------------------------------------------------------------------------------===//
14+
15+
import struct Foundation.Data
16+
17+
// https://cloud.tencent.com/document/product/583/12513
18+
19+
extension APIGateway.Response {
20+
public init<T: Encodable>(
21+
statusCode: HTTPResponseStatus,
22+
headers: HTTPHeaders = [:],
23+
codableBody: T?
24+
) {
25+
var headers = headers
26+
headers["Content-Type"] = MIME.json.rawValue
27+
self.headers = headers
28+
do {
29+
self.body = String(
30+
data: try APIGateway.defaultJSONEncoder.encode(codableBody),
31+
encoding: .utf8
32+
) ?? ""
33+
self.statusCode = statusCode
34+
} catch let err {
35+
self.body = #"{"errorType":"FunctionError","errorMsg":"\#(err.localizedDescription)"}"#
36+
self.statusCode = .internalServerError
37+
}
38+
self.isBase64Encoded = false
39+
}
40+
41+
public init(
42+
statusCode: HTTPResponseStatus,
43+
headers: HTTPHeaders = [:],
44+
type: MIME? = nil,
45+
body: String? = nil
46+
) {
47+
self.statusCode = statusCode
48+
var headers = headers
49+
if let type = type?.rawValue {
50+
headers["Content-Type"] = type
51+
} else {
52+
headers["Content-Type"] = MIME.text.rawValue
53+
}
54+
self.headers = headers
55+
self.body = body ?? ""
56+
self.isBase64Encoded = false
57+
}
58+
59+
public init(
60+
statusCode: HTTPResponseStatus,
61+
headers: HTTPHeaders = [:],
62+
type: MIME? = nil,
63+
body: Data
64+
) {
65+
self.statusCode = statusCode
66+
var headers = headers
67+
if let type = type?.rawValue {
68+
headers["Content-Type"] = type
69+
} else {
70+
headers["Content-Type"] = MIME.octet.rawValue
71+
}
72+
self.headers = headers
73+
self.body = body.base64EncodedString()
74+
self.isBase64Encoded = true
75+
}
76+
}

0 commit comments

Comments
 (0)