Skip to content

Commit 613d438

Browse files
committed
Refine APIGateway.Response APIs
1 parent 0918962 commit 613d438

File tree

3 files changed

+49
-54
lines changed

3 files changed

+49
-54
lines changed

Examples/CloudFunctions/Sources/APIGateway/main.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ struct APIGatewayProxySCF: EventLoopSCFHandler {
4242

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

Sources/TencentSCFEvents/APIGateway/Response+Init.swift

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,63 +17,59 @@ import struct Foundation.Data
1717
// https://cloud.tencent.com/document/product/583/12513
1818

1919
extension APIGateway.Response {
20-
public init<T: Encodable>(
20+
public init(
2121
statusCode: HTTPResponseStatus,
2222
headers: HTTPHeaders = [:],
23-
codableBody: T?
23+
body: @autoclosure () throws -> Body = .null
2424
) {
25-
var headers = headers
26-
headers["Content-Type"] = MIME.json.rawValue
27-
self.headers = headers
25+
let rawBody: Body
2826
do {
29-
self.body = String(
30-
data: try APIGateway.defaultJSONEncoder.encode(codableBody),
31-
encoding: .utf8
32-
) ?? ""
33-
self.statusCode = statusCode
34-
} catch let err as EncodingError {
35-
self.body = #"{"error":"EncodingError","message":"\#("\(err)".jsonEncoded())"}"#
36-
self.statusCode = .internalServerError
27+
rawBody = try body()
3728
} catch let err {
38-
self.body = #"{"error":"UnexpectedError","message":"\#("\(err)".jsonEncoded())"}"#
29+
self.headers = headers.merging(["Content-Type": "application/json"]) { (_, default) in `default` }
3930
self.statusCode = .internalServerError
31+
self.isBase64Encoded = false
32+
if let err = err as? EncodingError {
33+
self.body = #"{"error":"EncodingError","message":"\#("\(err)".jsonEncoded())"}"#
34+
} else {
35+
self.body = #"{"error":"UnexpectedError","message":"\#("\(err)".jsonEncoded())"}"#
36+
}
37+
return
4038
}
41-
self.isBase64Encoded = false
42-
}
4339

44-
public init(
45-
statusCode: HTTPResponseStatus,
46-
headers: HTTPHeaders = [:],
47-
type: MIME? = nil,
48-
body: String? = nil
49-
) {
5040
self.statusCode = statusCode
51-
var headers = headers
52-
if let type = type?.rawValue {
53-
headers["Content-Type"] = type
54-
} else {
55-
headers["Content-Type"] = MIME.text.rawValue
41+
self.headers = headers.merging(["Content-Type": rawBody.defaultMIME]) { (custom, _) in custom }
42+
43+
switch rawBody {
44+
case .data(let dataBody):
45+
self.body = dataBody.base64EncodedString()
46+
self.isBase64Encoded = true
47+
case .json(let stringBody), .string(let stringBody):
48+
self.body = stringBody
49+
self.isBase64Encoded = false
50+
case .null:
51+
self.body = ""
52+
self.isBase64Encoded = true
5653
}
57-
self.headers = headers
58-
self.body = body ?? ""
59-
self.isBase64Encoded = false
6054
}
6155

62-
public init(
63-
statusCode: HTTPResponseStatus,
64-
headers: HTTPHeaders = [:],
65-
type: MIME? = nil,
66-
body: Data
67-
) {
68-
self.statusCode = statusCode
69-
var headers = headers
70-
if let type = type?.rawValue {
71-
headers["Content-Type"] = type
72-
} else {
73-
headers["Content-Type"] = MIME.octet.rawValue
56+
public enum Body {
57+
case json(String)
58+
case data(Data)
59+
case string(String)
60+
case null
61+
62+
public static func codable<T: Encodable>(_ body: T) throws -> Self {
63+
return .json(String(data: try APIGateway.defaultJSONEncoder.encode(body), encoding: .utf8) ?? "")
64+
}
65+
66+
var defaultMIME: String {
67+
switch self {
68+
case .json: return "application/json"
69+
case .data: return "application/octet-stream"
70+
case .string: return "text/plain"
71+
case .null: return "text/plain"
72+
}
7473
}
75-
self.headers = headers
76-
self.body = body.base64EncodedString()
77-
self.isBase64Encoded = true
7874
}
7975
}

Tests/TencentSCFEventsTests/APIGatewayTests.swift

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,7 @@ class APIGatewayTests: XCTestCase {
169169

170170
let resp = APIGateway.Response(
171171
statusCode: .ok,
172-
type: .text,
173-
body: "abc123"
172+
body: .string("abc123")
174173
)
175174
let expectedJson = #"{"body":"abc123","headers":{"Content-Type":"text\/plain"},"isBase64Encoded":false,"statusCode":200}"#
176175

@@ -192,7 +191,7 @@ class APIGatewayTests: XCTestCase {
192191
let body = #"{"hello":"swift"}"#
193192
let resp = APIGateway.Response(
194193
statusCode: .ok,
195-
body: body.data(using: .utf8)!
194+
body: .data(body.data(using: .utf8)!)
196195
)
197196
let expectedJson = #"{"body":"\#(body.data(using: .utf8)!.base64EncodedString())","headers":{"Content-Type":"application\/octet-stream"},"isBase64Encoded":true,"statusCode":200}"#
198197

@@ -217,7 +216,7 @@ class APIGatewayTests: XCTestCase {
217216
let point = Point(x: 1.01, y: -0.01)
218217
let resp = APIGateway.Response(
219218
statusCode: .ok,
220-
codableBody: point
219+
body: try .codable(point)
221220
)
222221
let expectedJson = [
223222
#"{"body":"{\"x\":1.01,\"y\":-0.01}","headers":{"Content-Type":"application\/json"},"isBase64Encoded":false,"statusCode":200}"#,
@@ -240,7 +239,7 @@ class APIGatewayTests: XCTestCase {
240239
encoder.outputFormatting = .sortedKeys
241240

242241
let resp = APIGateway.Response(statusCode: .ok)
243-
let expectedJson = #"{"body":"","headers":{"Content-Type":"text\/plain"},"isBase64Encoded":false,"statusCode":200}"#
242+
let expectedJson = #"{"body":"","headers":{"Content-Type":"text\/plain"},"isBase64Encoded":true,"statusCode":200}"#
244243

245244
var data: Data?
246245
XCTAssertNoThrow(data = try encoder.encode(resp))
@@ -260,8 +259,8 @@ class APIGatewayTests: XCTestCase {
260259
let mime = "application/x-javascript"
261260
let resp = APIGateway.Response(
262261
statusCode: .ok,
263-
type: .init(rawValue: mime),
264-
body: "console.log(\"Hello world!\");"
262+
headers: ["Content-Type": mime],
263+
body: .string("console.log(\"Hello world!\");")
265264
)
266265
let expectedJson = #"{"body":"console.log(\"Hello world!\");","headers":{"Content-Type":"application\/x-javascript"},"isBase64Encoded":false,"statusCode":200}"#
267266

@@ -290,7 +289,7 @@ class APIGatewayTests: XCTestCase {
290289

291290
let resp = APIGateway.Response(
292291
statusCode: .ok,
293-
codableBody: NotReallyEncodable()
292+
body: try .codable(NotReallyEncodable())
294293
)
295294
let expectedJson = #"{"body":"{\"error\":\"EncodingError\",\"message\":\"invalidValue(\\\"NotReallyEncodable\\\", Swift.EncodingError.Context(codingPath: [], debugDescription: \\\"You\\\\'re testing something not really Encodable! Good luck.\\\"\"}","headers":{"Content-Type":"application\/json"},"isBase64Encoded":false,"statusCode":500}"#
296295

0 commit comments

Comments
 (0)