我一直在尝试在 Lambda 和 HTTP API 网关中设置一个以 Kotlin 作为后端的微服务。我已经达到了在 HTTP API 网关中正确显示来自 lambda 的响应。它没有给我在响应、正文和标头中传递的状态,而是始终返回 HTTP 状态代码 200。
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html 根据这篇文章,唯一需要自定义的就是返回一个像这样的特定格式的响应
{
"cookies" : ["cookie1", "cookie2"],
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headername": "headervalue", ... },
"body": "Hello from Lambda!"
}
我在我的 lambda 函数中启用了日志,我可以肯定地看到返回的响应是相同的格式
{
"isBase64Encoded": false,
"headers": {
"Content-type": "application/json"
},
"body": "some body",
"statusCode": 409
}
一段时间后,我决定看看这种方法是否普遍有效。我使用 javascript 创建了以下示例 lambda
exports.handler = async (event, context) => {
console.log('Received event:', JSON.stringify(event, null, 2));
const headers = {
'Content-Type': 'application/json',
};
const statusCode = '400';
const body = JSON.stringify({method: `${event.httpMethod}`});
const response = {
statusCode,
body,
headers,
};
console.log(response);
// return `{statusCode: '${statusCode}', body: {'created': 'true'}, headers: {'content-type': 'application/json'}}`;
return response;
};
上面的例子工作得很好。虽然事实证明 API Gateway 需要一个对象,而不仅仅是一个字符串作为 Lambda 的响应传递。
这是我在 Kotlin 中使用的代码
val jsonResponse = json {
"statusCode" To 409
"isBase64Encoded" To false
"headers" To json {
"content-type" To "application/json"
}
"body" To "some body"
}
logger.info(jsonResponse.toString())
return jsonResponse
fun json(build: JsonObjectBuilder.() -> Unit): JSONObject {
return JsonObjectBuilder().json(build)
}
class JsonObjectBuilder {
private val deque: Deque<JSONObject> = ArrayDeque()
fun json(build: JsonObjectBuilder.() -> Unit): JSONObject {
deque.push(JSONObject())
this.build()
return deque.pop()
}
infix fun <T> String.To(value: T) {
deque.peek().put(this, value)
}
}
JSONObject 类来自 org.json.json 库(maven)
也许 API Gateway 需要不同的对象格式,或者 Lambda 不能很好地与 JSONObject 配合使用,但这对我来说不起作用。
有没有人试过这个?我在这里想念什么?