Я использую 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?
Спасибо за ваши ответы!