首页 > 解决方案 > 如何将带有 HTTP 状态和正文的 Java(Kotlin)的 AWS lamda 自定义响应传播到 HTTP API 网关

问题描述

我一直在尝试在 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 配合使用,但这对我来说不起作用。

有没有人试过这个?我在这里想念什么?

标签: kotlinaws-lambdaaws-http-api

解决方案


推荐阅读