2017-02-08 36 views
5

私はLambdaコンソールテストからのテストに成功し、API Gatewayから呼び出された場合には502(Bad Gateway)で失敗する単純なC#Aws Lambda関数を持っています。ラムダトリガーオプション)とも私は郵便配達を使用している場合(この最初の関数は、オープンアクセス(保障なしを持っている))AWS-API GatewayからLambdaへの投稿

// request header 
    Content-Type: application/json 

// request body 
    { 
     "userid":22, 
     "files":["File1","File2","File3","File4"] 
    } 

私は、ログに取得するエラーは次のとおりです。

Wed Feb 08 14:14:54 UTC 2017 : Endpoint response body before transformations: { 
    "errorType": "NullReferenceException", 
    "errorMessage": "Object reference not set to an instance of an object.", 
    "stackTrace": [ 
    "at blahblahmynamespace.Function.FunctionHandler(ZipRequest input, ILambdaContext context)", 
    "at lambda_method(Closure , Stream , Stream , ContextInfo)" 
    ] 
} 

それはのように思えます投稿されたオブジェクトがラムダ入力引数に渡されていません。

// Lambda function 
    public LambdaResponse FunctionHandler(ZipRequest input, ILambdaContext context) 
     { 
      try 
      { 
       var logger = context.Logger; 
       var headers = new Dictionary<string, string>(); 

       if (input == null || input.files.Count == 0) 
       { 
        logger.LogLine($"input was null"); 
        headers.Add("testheader", "ohdear"); 
        return new LambdaResponse { body = "fail", headers = headers, statusCode = HttpStatusCode.BadRequest }; 
       } 
       else 
       { 
        logger.LogLine($"recieved request from user{input?.userid}"); 
        logger.LogLine($"recieved {input?.files?.Count} items to zip"); 
        headers.Add("testheader", "yeah"); 
        return new LambdaResponse { body = "hurrah", headers = headers, statusCode = HttpStatusCode.OK }; 
       } 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
     } 

//ラムダ応答/ ZipRequestクラス

public class LambdaResponse 
{ 

    public HttpStatusCode statusCode { get; set; } 
    public Dictionary<string, string> headers { get; set; } 
    public string body { get; set; } 
} 
public class ZipRequest 
{ 
    public int userid { get; set; } 
    public IList<string> files { get; set; } 
} 

答えて

3

以下のコードAPIゲートウェイにラムダプロキシの統合を使用する場合は、あなたのFunctionHandlerへの最初のパラメータは、あなたのPOSTのボディではありませんそれ以外のAPIゲートウェイで作成されたオブジェクトであり、LambdaRequestを呼び出します。これらの変更をサンプルコードに適用してみてください。追加:

public class LambdaRequest 
{ 
    public string body { get; set; } 
} 
はにあなたのハンドラのプロトタイプを変更

ZipRequest input = JsonConvert.DeserializeObject<ZipRequest>(req.Body); 

フルLambdaRequestオブジェクトは、AWSのドキュメントにInput Format of a Lambda Function for Proxy Integrationの下で文書化、および含まれているHTTP:

public LambdaResponse FunctionHandler(LambdaRequest req, ILambdaContext context) 

そしてFunctionHandlerアドオン内部ヘッダー、HTTPメソッド、クエリ文字列、本文、およびその他のいくつかの要素が含まれます。

5

これは、OPが質問したときには利用できなかったかもしれませんが、APIゲートウェイを使用してラムダ関数を呼び出すと、特定の応答オブジェクトが提供されます。

前述のドキュメントApi Gateway Simple Proxy for Lambda Input Formatに記載されているように、APIゲートウェイは入力引数をかなり冗長なラッパーにラップします。同様に冗長な応答オブジェクトも必要です。

ただし、カスタムの要求および応答オブジェクトを作成する必要はありません。 AWSチームはAmazon.Lambda.APIGatewayEventsライブラリを提供しています。これはNuGetでも利用できます。このライブラリには、APIGatewayProxyRequestAPIGatewayProxyResponseの既製品が含まれています。

リクエストのBodyは、JSONオブジェクトではなく文字列であるため、手動でデシリアライズする必要があります。これは柔軟性のために行われたと思いますか?

関数の例は次のようになります。これは、AWSツールによって提供されるデフォルト関数の変更です:

public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context) 
    { 
     var bodyString = request?.Body; 

     if (!string.IsNullOrEmpty(bodyString)) 
     { 
      dynamic body = JsonConvert.DeserializeObject(bodyString); 

      if (body.input != null) 
      { 
       body.input = body.input?.ToString().ToUpper(); 

       return new APIGatewayProxyResponse 
       { 
        StatusCode = 200, 
        Body = JsonConvert.SerializeObject(body) 
       }; 
      } 
     } 

     return new APIGatewayProxyResponse 
     { 
      StatusCode = 200 
     }; 
    } 
関連する問題