AWS SAM JAVA - Как передать только тело запроса на AWS Lambda? - PullRequest
0 голосов
/ 23 января 2020

Я использую AWS SAM с Java11 и пытаюсь выполнить функцию POST. Я основан на шаблоне Hello world. Я пытаюсь отобразить (при возврате) полезную нагрузку моего запроса.

Вот так выглядит мой template.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  mycustom-backend

  Sample SAM Template for mycustom-backend

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 20
  Api:
    Cors:
      AllowMethods: "'POST,OPTIONS'"
      AllowHeaders: "'*'"
      AllowOrigin: "'*'"
      AllowCredentials: "'*'"


Resources:
  mycustomBackendFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: mycustomBackendFunction
      Handler: helloworld.App::handleRequest
      Runtime: java11
      MemorySize: 512
      Events:
        mycustomBackend:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /mycustom
            Method: post

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  mycustomBackendApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/mycustom/"
  mycustomBackendFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt mycustomBackendFunction.Arn
  mycustomBackendFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt mycustomBackendFunctionRole.Arn

И вот так выглядит моя лямбда:

package helloworld;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import model.RequestWrapper;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

/**
 * Handler for requests to Lambda function.
 */
public class App implements RequestHandler<RequestWrapper, Object> {

    public Object handleRequest(final RequestWrapper input, final Context context) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put("X-Custom-Header", "application/json");
        headers.put("Access-Control-Allow-Origin", "*");
        headers.put("Access-Control-Allow-Credentials", "true");
        try {
            Map<String, Object> payload = input.getPayload();
            final String pageContents = this.getPageContents("https://checkip.amazonaws.com");
            String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\", \"value\":  \"%s\"}", pageContents, input);
            return new GatewayResponse(output, headers, 200);
        } catch (IOException e) {
            return new GatewayResponse("{}", headers, 500);
        }
    }

    private String getPageContents(String address) throws IOException{
        URL url = new URL(address);
        try(BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) {
            return br.lines().collect(Collectors.joining(System.lineSeparator()));
        }
    }
}

Вот как выглядит RequestWrapper:

package model;

import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.Map;

/**
 * It represent a request wrapper.
 */
@Data
public class RequestWrapper {
private String action;
private Map<String, Object> payload;

@Override
public String toString() {
        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
        .append("action", action)
        .append("payload", payload)
        .toString();
    }
}

Моя проблема: как я могу передать только тело моего запроса в мою функцию Lambda?

В настоящее время вся информация запроса передается в лямбда-функцию, поэтому ее нельзя сериализовать в мой объект RequestWrapper. При такой конфигурации YAML запрос на интеграцию по умолчанию активирует опцию интеграции Lambda Proxy (поэтому весь контент запроса передается в Lambda).

Можно ли передать только тело запроса, используя AWS SAM?

Спасибо за ваши ответы!

...