Было сложно отследить это, но все сводится к необходимости поставить RequestTemplate
на AWS::ApiGateway::Method
. Я сделал это в шаблоне CloudFormation:
MethodArticleIdGet:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: GET
ResourceId: !Ref ResourceArticleId
RestApiId: !Ref BlogRestApi
AuthorizationType: NONE
Integration:
IntegrationHttpMethod: POST
Type: AWS_PROXY
RequestTemplates:
application/json: !Ref ParamRequestMappingTemplate
Uri: !Join [ "", ['arn:', !Ref 'AWS::Partition', ':apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt [ BFunctionGetArticle, Arn ], '/invocations' ] ]
, а затем добавил ParamRequestMappingTemplate
:
Parameters:
<snip>
ParamRequestMappingTemplate:
Type: String
Description: 'Read from resources/templates'
<snip>
, чтобы я мог ввести параметр через --parameter-overrides
в вызове cloudformation deploy
со ссылкой на файл .vsl
, содержащий:
#set($allParams = $input.params())
{
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
}
, который является модификацией сценария AWS, который передает все заголовки, аргументы пути и параметры запроса как сопоставленные элементы .
Затем я смоделировал параметры запроса в следующем классе:
public class RequestParams {
String path;
Map<String, String> header;
Map<String, String> queryString;
}
, а затем переделал метод Lamabda и обработчика:
public class GetArticleHandler implements RequestHandler<RequestParams, Response<Article>> {
Injector injector = Guice.createInjector(new GetArticleHandlerModule());
private GetArticleService getArticleService = injector.getInstance(GetArticleService.class);
public void setGetArticleService(GetArticleService getArticleService) {
this.getArticleService = getArticleService;
}
@Override
public Response<Article> handleRequest(RequestParams params, Context context) {
LOGGER.init(context, "GetArticle", null);
LOGGER.info(this, params.getPath());
Article article = getArticleService.get(params.getPath());
return new Response<>(article);
}
}
С предоставлением этого , ошибка исчезла.
Хотя следует отметить, что уровень шлюза API также требует, чтобы ответ был смоделирован как:
public class Response<B> {
@JsonProperty("isBase64Encoded")
boolean isBase64Encoded;
int statusCode;
Map<String, String> headers;
B body;
public Response(B body) {
this.setBase64Encoded(false);
this.setStatusCode(200);
this.setHeaders(Map.of("Access-Control-Allow-Origin", "*"));
this.setBody(body);
}
}
У меня все еще возникают проблемы с этим, поскольку ответ после того, как Джексон сериализации упорно выходов:
Tue May 26 08:25:04 UTC 2020 : Endpoint response body before transformations: {"statusCode":200,"headers":{"Access-Control-Allow-Origin":"*"},"body":{"tags":[]},"base64Encoded":false}
другими словами, это всегда serialises isBase64Encoded
в base64Encoded
независимо от того, что я делаю
1035 * и это приводит к ошибке:.
Tue May 26 08:25:04 UTC 2020 : Execution failed due to configuration error: Malformed Lambda proxy response
Tue May 26 08:25:04 UTC 2020 : Method completed with status: 502
о человечество!