0

Ich verschiebe einige Scala-Code zu AWS Lambda und ich beabsichtige, es über AWS API Gateway ausgesetzt, aber ich habe gekämpft, um die ganze Sache zu arbeiten, sobald ich eine habe Parameter.Invoke AWS Lambda mit AWS API Gateway

Meine (sehr einfach) Code sieht wie folgt aus:

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

ich die eingebaute Glas auf Lambda hochgeladen und getestet es in der AWS-Konsole durch ein Test-Event zu schaffen. Es gibt die richtige Antwort wie erwartet zurück.

Allerdings möchte ich dieses Lambda vom API-Gateway aufgerufen werden. Ich habe beide Lambda-Proxy-Integration verwendet und auch meine eigenen Body Mapping Templates definiert. Ich kann nicht scheinen, damit es funktioniert und ich erhalte:

{ 
    "message": "Internal server error" 
} 

mit Protokollen:

Execution log for request test-request Mon Jul 03 16:23:21 UTC 2017 : Starting execution for request: test-invoke-request Mon Jul 03 16:23:21 UTC 2017 : HTTP Method: GET, Resource Path: /car/aaa Mon Jul 03 16:23:21 UTC 2017 : Method request path: {carReg=aaa} Mon Jul 03 16:23:21 UTC 2017 : Method request query string: {} Mon Jul 03 16:23:21 UTC 2017 : Method request headers: {} Mon Jul 03 16:23:21 UTC 2017 : Method request body before transformations: Mon Jul 03 16:23:21 UTC 2017 : Endpoint request 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 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************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+}, Accept=application/json, User-Agent=AmazonAPIGateway_9dwaaf2mdg, X-Amz-Security-Token=FQoDYXdzENn//////////wEaDMO73KD0CHVmggvYvSK3A8H1fpDgYiNK3HDD3ESe1aKYbv1HlGSQ85at3gRGA3kunmxVCxWbXNqR4ojBCn4hvBzdv1/iWD9xRzZQEtnQeDoO9NTuiBdYaXKgwjGozPKF/46X71f0sCt/Mm9i8EDtt3igEezJIhAF3OvYcdv2NBF3L0mRMMQKp4Vy+aC0mKu4ggadyLe+KYvmch8/AiZPlrxC1AtqwNGyWpSe1JqxeEXQGXIA5JsfwGpnpAB5IUec2r3Bd09zUFk/DCC80l9d4BLnhYAUn7xzrKYzisSEQitmhnTR3HijEYE6AJzJjFR+z2PqqVKvtgKQ [TRUNCATED] Mon Jul 03 16:23:21 UTC 2017 : Endpoint request body after transformations: { "message" : "foo" } Mon Jul 03 16:23:21 UTC 2017 : Endpoint response body before transformations: {"errorMessage":"An error occurred during JSON parsing","errorType":"java.lang.RuntimeException","stackTrace":[],"cause":{"errorMessage":"com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: [email protected]; line: 1, column: 1]","errorType":"java.io.UncheckedIOException","stackTrace":[],"cause":{"errorMessage":"Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: [email protected]; line: 1, column: 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 [TRUNCATED] Mon Jul 03 16:23:21 UTC 2017 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=ede9aaed-600b-11e7-834e-47baf0a4e23f, Connection=keep-alive, Content-Length=1252, X-Amz-Function-Error=Unhandled, Date=Mon, 03 Jul 2017 16:23:20 GMT, X-Amzn-Trace-Id=root=1-595a6f79-c065d6038ba3209743378112;sampled=0, Content-Type=application/json} Mon Jul 03 16:23:21 UTC 2017 : Execution failed due to configuration error: Output mapping refers to an invalid method response: 200 Mon Jul 03 16:23:21 UTC 2017 : Method completed with status: 500

Es gibt eine Null auf dem Weg meiner ARN, aber ich denke, das ist, weil ich keine Authentifizierung haben eingestellt, was an diesem Punkt beabsichtigt ist. Ich glaube nicht, dass dies der Grund für den Fehler wäre.

Ansonsten habe ich versucht, den Content-Type für den Körper sowohl als Anwendung/JSON und Text/Plain zu definieren. Keiner scheint zu funktionieren und selbst mit text/plain scheint AWS json zu erwarten. Ich hatte erwartet, dass eine Zeichenfolge trotzdem gültig ist.

Was mache ich falsch? Was ist der vollständige Ausdruck, den ich in meine Body-Mapping-Vorlage einfügen sollte? Und wie sollte die Schemadefinition in meinem Modell aussehen? Ich bin nicht in der Lage, ein richtiges Modell für Klartext zu definieren.

Ich bin sicher, dass dies etwas ist wirklich einfach und ich bin nur etwas fehlt ...

Antwort

2

Die Antwort, die Sie an den Server senden, hängt davon ab, ob Sie die Lambda-Proxy-Integration verwenden oder nicht. Die Verwendung der Proxy-Integration ist auf der API-Gateway-Seite einfacher einzurichten, aber Ihr Lambda muss etwas mehr arbeiten, da das Gateway Ihnen eine Menge Zeug senden und ein bestimmtes Format in der Antwort verlangen wird. Für Proxy-Integration muss das Antwortformat wie folgt aussehen:

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

Es gibt mehr hier: 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

Wenn Sie keine Proxy-Integration verwenden Sie einrichten Body-Mapping für Ihre Parameter in der API-Gateway-Integration benötigen für das betreffende HTTP-Verb, um die API-Parameter den Lambda-Parametern anzupassen. Es gibt eine gute Erklärung in der akzeptierten Antwort hier: How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway

+0

Hey, danke. Ich möchte nicht wirklich, dass mein Code auf AWS-Bibliotheken angewiesen ist, also entschied ich mich für die Body Mapping-Alternative, aber Ihre Antwort half mir dabei, es herauszufinden. Ich habe mir diesen Beitrag gestern angesehen, muss aber zu müde gewesen sein und die Lösung komplett vermisst haben. Vielen Dank! – redwulf

1

Mit Lambda-Proxy, müssen Sie einen Zeichenfolge JSON zurück.

Mit Lambda können Sie JSON von Ihrem Lambda zurückgeben und dann Ihre API Gateway Körper Mapping Vorlage für Sie stringifizieren.

Für zusätzlichen Kontext und Beispiel siehe this page from Serverless docs.

Verwandte Themen