【问题标题】:Invoke AWS Lambda with AWS API Gateway使用 AWS API Gateway 调用 AWS Lambda
【发布时间】:2017-12-07 00:08:30
【问题描述】:

我正在将一些 scala 代码移动到 AWS Lambda,并打算通过 AWS API Gateway 公开它,但我一直在努力让整个事情在我有一个参数后立即工作。

我的(非常简单的)代码如下所示:

class HelloService {
  def hello(name: String) = {
    "hello there, " + name
  }
}

我将构建的 jar 上传到 Lambda,并通过创建测试事件在 AWS 控制台中对其进行了测试。它按预期返回正确的响应。

但是,我希望 API 网关调用此 Lambda。我既使用了 Lambda 代理集成,也定义了我自己的身体映射模板。我似乎无法让它工作,我不断得到:

{
  "message": "Internal server error"
}

带日志:

请求测试请求的执行日志 Mon Jul 03 16:23:21 UTC 2017 : 开始执行请求:test-invoke-request Mon Jul 03 2017 年 16:23:21 UTC:HTTP 方法:GET,资源路径:/car/aaa Mon Jul 03 16:23:21 UTC 2017:方法请求路径:{carReg=aaa} Mon Jul 03 16:23:21 UTC 2017:方法请求查询字符串:{} Mon Jul 03 2017 年 16:23:21 UTC:方法请求标头:{} Mon Jul 03 16:23:21 UTC 2017 :转换前的方法请求正文:Mon Jul 03 2017 年 16:23:21 UTC:端点请求 URI: https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:879461422967:function:getCarData/invocations 2017 年 7 月 3 日星期一 16:23:21 UTC:端点请求标头: {x-amzn-lambda-integration-tag=测试请求, 授权=************************************************ ****************************************************** ****************************************************** ****************************************************** ****************************************************** ****************************************************** ******************************f8c749, X-Amz-Date=20170703T162321Z, x-amzn-apigateway-api-id= 9dwaaf2mdg, X-Amz-Source-Arn=arn:aws:execute-api:eu-west-1:879461422967:9dwaaf2mdg/null/GET/car/{carReg+}, 接受=应用程序/json,用户代理=AmazonAPIGateway_9dwaaf2mdg, X-AMZ-安全令牌= FQoDYXdzENn ////////// wEaDMO73KD0CHVmggvYvSK3A8H1fpDgYiNK3HDD3ESe1aKYbv1HlGSQ85at3gRGA3kunmxVCxWbXNqR4ojBCn4hvBzdv1 / iWD9xRzZQEtnQeDoO9NTuiBdYaXKgwjGozPKF / 46X71f0sCt / Mm9i8EDtt3igEezJIhAF3OvYcdv2NBF3L0mRMMQKp4Vy + aC0mKu4ggadyLe + KYvmch8 / AiZPlrxC1AtqwNGyWpSe1JqxeEXQGXIA5JsfwGpnpAB5IUec2r3Bd09zUFk / DCC80l9d4BLnhYAUn7xzrKYzisSEQitmhnTR3HijEYE6AJzJjFR + z2PqqVKvtgKQ [截断] 2017 年 7 月 3 日星期一 16:23:21 UTC:端点请求正文之后 转换:{“消息”:“foo”} 2017 年 7 月 3 日星期一 16:23:21 UTC : 转换前的端点响应正文:{"errorMessage":"An JSON期间发生错误 解析","errorType":"java.lang.RuntimeException","stackTrace":[],"cause":{"errorMessage":"com.fasterxml.jackson.databind.JsonMappingException: 无法从 START_OBJECT 反序列化 java.lang.String 的实例 [来源: lambdainternal.util.NativeMemoryAsInputStream@e720b71;线:1, 柱子: 1]","errorType":"java.io.UncheckedIOException","stackTrace":[],"cause":{"errorMessage":"可以 不在 START_OBJECT 中反序列化 java.lang.String 的实例 [来源: lambdainternal.util.NativeMemoryAsInputStream@e720b71;线:1, 柱子: 1]","errorType":"com.fasterxml.jackson.databind.JsonMappingException","stackTrace":["com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)","com.fasterxml .jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:857)","com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java [截断] 2017 年 7 月 3 日星期一 16:23:21 UTC:端点响应标头: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=ede9aaed-600b-11e7-834e-47baf0a4e23f, 连接=保持活动,内容长度=1252, X-Amz-Function-Error=未处理,日期=星期一,2017 年 7 月 3 日 16:23:20 GMT, X-Amzn-Trace-Id=root=1-595a6f79-c065d6038ba3209743378112;sampled=0, Content-Type=application/json} 2017 年 7 月 3 日星期一 16:23:21 UTC : 由于配置错误,执行失败:输出映射指 无效的方法响应:200 Mon Jul 03 16:23:21 UTC 2017:方法 完成状态:500

我的 ARN 路径中有一个空值,但我想那是因为我没有设置身份验证,这正是此时的意图。我认为这不会是错误的原因。

除此之外,我尝试将正文的 Content-Type 定义为 application/json 和 text/plain。似乎没有任何工作,即使使用 text/plain,AWS 似乎也在期待 json。无论如何,我希望字符串是有效的 json。

我做错了什么?我应该在我的身体映射模板中输入什么完整的表达式?我的模型中的模式定义应该如何?我似乎无法为纯文本定义合适的模型。

我确定这真的很简单,我只是错过了一些东西......

【问题讨论】:

    标签: amazon-web-services aws-lambda aws-sdk aws-api-gateway aws-java-sdk


    【解决方案1】:

    您发送回服务器的响应取决于您是否使用 Lambda 代理集成。在 API 网关端使用代理集成更容易设置,但您的 Lambda 需要做更多的工作,因为网关将向您发送一堆东西并要求响应中的特定格式。对于代理集成,响应格式需要如下所示:

    {
        "isBase64Encoded": true|false,
        "statusCode": httpStatusCode,
        "headers": { "headerName": "headerValue", ... },
        "body": "..."
    }
    

    这里还有更多内容:http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on-proxy-resource

    如果您不使用代理集成,则需要在 API 网关集成中为相关 HTTP 动词的参数设置正文映射,以将 api 参数与 lambda 参数匹配。此处接受的答案中有一个很好的解释:How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway

    【讨论】:

    • 嘿,谢谢。我真的不希望我的代码依赖于 AWS 库,所以我选择了 Body Mapping 替代方案,但你的回答是帮助我解决这个问题。我昨天确实看过那个帖子,但一定是太累了,完全错过了解决方案。谢谢!
    【解决方案2】:

    使用 Lambda 代理,您必须返回字符串化的 JSON。

    使用 Lambda,您可以从 Lambda 返回 JSON,然后让 API Gateway 正文映射模板为您将其字符串化。

    有关其他上下文和示例,请参阅this page from Serverless docs

    【讨论】:

      猜你喜欢
      • 2017-05-29
      • 2020-10-01
      • 2017-10-30
      • 2017-09-19
      • 1970-01-01
      • 2019-08-11
      • 2021-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多