使用AWS API Gateway

时间:2017-07-03 16:32:53

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

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

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

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

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

但是,我希望API网关调用此Lambda。我已经使用了Lambda Proxy Integration并且还定义了我自己的Body Mapping模板。我似乎无法使它工作,我一直在努力:

{
  "message": "Internal server error"
}

包含日志:

  

请求测试请求的执行日志Mon Jul 03 16:23:21 UTC 2017:   开始执行请求:test-invoke-request Mon Jul 03   16:23:21 UTC 2017: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   16:23:21 UTC 2017:方法请求标题:{} 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   Mon Jul 03 16:23:21 UTC 2017:端点请求标头:   {X-AMZN-λ-集成标签=测试请求,   授权= ********* ************************************************** ************************************************** ************************************************** ************************************************** ************************************************** ****************************** f8c749,X-Amz-Date = 20170703T162321Z,x-amzn-apigateway-api-id = 9dwaaf2mdg,   X-AMZ-源-阿恩= ARN:AWS:执行-API:EU-西-1:879461422967:9dwaaf2mdg /空/ GET /汽车/ {carReg +},   Accept = application / json,User-Agent = AmazonAPIGateway_9dwaaf2mdg,   X-AMZ-安全令牌= FQoDYXdzENn ////////// wEaDMO73KD0CHVmggvYvSK3A8H1fpDgYiNK3HDD3ESe1aKYbv1HlGSQ85at3gRGA3kunmxVCxWbXNqR4ojBCn4hvBzdv1 / iWD9xRzZQEtnQeDoO9NTuiBdYaXKgwjGozPKF / 46X71f0sCt / Mm9i8EDtt3igEezJIhAF3OvYcdv2NBF3L0mRMMQKp4Vy + aC0mKu4ggadyLe + KYvmch8 / AiZPlrxC1AtqwNGyWpSe1JqxeEXQGXIA5JsfwGpnpAB5IUec2r3Bd09zUFk / DCC80l9d4BLnhYAUn7xzrKYzisSEQitmhnTR3HijEYE6AJzJjFR + z2PqqVKvtgKQ   [截止日期] Mon Jul 03 16:23:21 UTC 2017:终点请求正文之后   转换:{“message”:“foo”} Mon Jul 03 16:23:21 UTC 2017   :转换前的端点响应体:{“errorMessage”:“An   JSON期间发生错误   解析 “ ”ERRORTYPE“: ”了java.lang.RuntimeException“, ”堆栈跟踪“:[], ”原因“:{ ”的errorMessage“:” com.fasterxml.jackson.databind.JsonMappingException:   无法从START_OBJECT中反序列化java.lang.String的实例   令牌\ n在[来源:   lambdainternal.util.NativeMemoryAsInputStream@e720b71;行:1,   柱:   1] “ ”ERRORTYPE“: ”java.io.UncheckedIOException“, ”堆栈跟踪“:[], ”原因“:{ ”的errorMessage“:” 能   不要将START.OBJECT中的java.lang.String实例反序列化   令牌\ n在[来源:   lambdainternal.util.NativeMemoryAsInputStream@e720b71;行:1,   柱:   1] “ ”ERRORTYPE“: ”com.fasterxml.jackson.databind.JsonMappingException“, ”堆栈跟踪“:[ ”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   [截止日期] Mon Jul 03 16:23:21 UTC 2017:终点响应标题:   {X-AMZN重新映射-Content-Length的= 0,   的x AMZN-的requestId = ede9aaed-600B-11e7-834e-47baf0a4e23f,   Connection = keep-alive,Content-Length = 1252,   X-Amz-Function-Error =未处理,日期=星期一,2017年7月3日16:23:20 GMT,   X-AMZN-痕量-ID =根= 1-595a6f79-c065d6038ba3209743378112;采样= 0,   Content-Type = application / json} Mon Jul 03 16:23:21 UTC 2017:   由于配置错误导致执行失败:输出映射是指   无效的方法响应:200 Mon Jul 03 16:23:21 UTC 2017:方法   完成状态:500

我的ARN路径中有一个空值,但我想这是因为我没有认证集,这就是目前的意图。我认为这不会是错误的原因。

除此之外,我已经尝试将body的Content-Type定义为application / json和text / plain。似乎没有工作,甚至使用text / plain,AWS似乎期待json。无论如何,我期望一个字符串是有效的json。

我做错了什么?我应该在Body Mapping模板中放入什么表达式?我的模型中的模式定义应该如何?我似乎无法为纯文本定义合适的模型。

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

2 个答案:

答案 0 :(得分:2)

使用Lambda Proxy,您必须返回一个字符串化的JSON。

使用Lambda,您可以从Lambda返回JSON,然后让您的API Gateway主体映射模板为您进行字符串化。

有关其他背景和示例,请参阅this page from Serverless docs

答案 1 :(得分:2)

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

<meta>

此处还有更多内容: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网关集成中为您的参数设置参数的主体映射,以便将api参数与lambda参数相匹配。在接受的答案中有一个很好的解释:How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway