Mon*_*key 87 amazon-web-services aws-lambda aws-api-gateway
例如,如果我想为无效参数返回特定的400错误,或者当lambda函数调用导致创建时返回201.
我想有不同的http状态代码,但看起来api网关总是返回200状态代码,即使lambda函数返回错误.
ac3*_*360 71
这是返回自定义HTTP状态代码和自定义的最快方法errorMessage:
在API网关仪表板中,执行以下操作:
为您之前创建的每个HTTP状态代码添加集成响应.确保选中输入直通.使用lambda错误正则表达式来识别从lambda函数返回错误消息时应使用的状态代码.例如:
// Return An Error Message String In Your Lambda Function
return context.fail('Bad Request: You submitted invalid input');
// Here is what a Lambda Error Regex should look like.
// Be sure to include the period and the asterisk so any text
// after your regex is mapped to that specific HTTP Status Code
Bad Request: .*
Run Code Online (Sandbox Code Playgroud)您的API网关路由应该返回:
HTTP Status Code: 400
JSON Error Response:
{
errorMessage: "Bad Request: You submitted invalid input"
}
Run Code Online (Sandbox Code Playgroud)我认为无法复制这些设置并将其重复用于不同的方法,因此我们有很多烦人的冗余手动输入!
我的集成响应如下所示:

Eri*_*oom 69
每20-9-2016更新一次
亚马逊最终使用Lambda Proxy集成轻松实现了这一目标.这允许您的Lambda函数返回正确的HTTP代码和标头:
let response = {
statusCode: '400',
body: JSON.stringify({ error: 'you messed up!' }),
headers: {
'Content-Type': 'application/json',
}
};
context.succeed(response);
Run Code Online (Sandbox Code Playgroud)
在API网关中说再见请求/响应映射!
选项2
使用aws-serverless-express将现有的Express应用程序与Lambda/API Gateway集成.
ken*_*gen 18
为了能够将自定义错误对象作为JSON返回,您必须跳过几个环节.
首先,您必须使Lambda失败并将其传递给字符串化的JSON对象:
exports.handler = function(event, context) {
var response = {
status: 400,
errors: [
{
code: "123",
source: "/data/attributes/first-name",
message: "Value is too short",
detail: "First name must contain at least three characters."
},
{
code: "225",
source: "/data/attributes/password",
message: "Passwords must contain a letter, number, and punctuation character.",
detail: "The password provided is missing a punctuation character."
},
{
code: "226",
source: "/data/attributes/password",
message: "Password and password confirmation do not match."
}
]
}
context.fail(JSON.stringify(response));
};
Run Code Online (Sandbox Code Playgroud)
接下来,为要返回的每个状态代码设置正则表达式映射.使用我在上面定义的对象,你可以设置这个正则表达式为400:
.*"状态":400*
最后,设置映射模板以从Lambda返回的errorMessage属性中提取JSON响应.映射模板如下所示:
$ input.path( '$.的errorMessage')
我写了一篇关于此的文章,详细介绍了Lambda到API Gateway的响应流程:http: //kennbrodhagen.net/2016/03/09/how-to-return-a-custom-error-object -and状态码,从-API网关与-拉姆达/
1)通过选中API网关资源定义的"集成请求"屏幕上标有"使用Lambda代理集成"的复选框,配置API网关资源以使用Lambda代理集成.(或者在你的cloudformation/terraform/serverless/etc配置中定义它)
2)以两种方式更改lambda代码
event适当地处理传入(第一个函数参数).它不再仅仅是裸负载,它代表整个HTTP请求,包括标头,查询字符串和正文.以下示例.关键是JSON主体将是需要显式JSON.parse(event.body)调用的字符串(不要忘记try/catch这一点).示例如下.statusCode,body和headers.
body应该是一个字符串,所以请JSON.stringify(payload)根据需要statusCode 可以是一个数字headers 是标题名称对象的对象{
"resource": "/example-path",
"path": "/example-path",
"httpMethod": "POST",
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Content-Type": "application/json",
"Host": "exampleapiid.execute-api.us-west-2.amazonaws.com",
"User-Agent": "insomnia/4.0.12",
"Via": "1.1 9438b4fa578cbce283b48cf092373802.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "oCflC0BzaPQpTF9qVddpN_-v0X57Dnu6oXTbzObgV-uU-PKP5egkFQ==",
"X-Forwarded-For": "73.217.16.234, 216.137.42.129",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"queryStringParameters": {
"bar": "BarValue",
"foo": "FooValue"
},
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"accountId": "666",
"resourceId": "xyz",
"stage": "dev",
"requestId": "5944789f-ce00-11e6-b2a2-dfdbdba4a4ee",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": null,
"sourceIp": "73.217.16.234",
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "insomnia/4.0.12",
"user": null
},
"resourcePath": "/example-path",
"httpMethod": "POST",
"apiId": "exampleapiid"
},
"body": "{\n \"foo\": \"FOO\",\n \"bar\": \"BAR\",\n \"baz\": \"BAZ\"\n}\n",
"isBase64Encoded": false
}
Run Code Online (Sandbox Code Playgroud)
callback(null, {
statusCode: 409,
body: JSON.stringify(bodyObject),
headers: {
'Content-Type': 'application/json'
}
})
Run Code Online (Sandbox Code Playgroud)
注释
-我相信,在方法上context,如context.succeed()已被弃用.它们不再记录,尽管它们似乎仍然有效.我认为编写回调API是正确的事情.
对于那些试图解决这个问题并且无法完成这项工作的人(像我一样),请查看该帖子的devkit评论(保存我的一天):
https://forums.aws.amazon.com/thread.jspa?threadID=192918
完全在下面复制:
我自己也有这个问题,我相信新行字符是罪魁祸首.
foo.*将匹配"foo"的出现,后跟任何字符,除了换行符.通常这可以通过添加'/ s'标志来解决,即"foo.*/s",但Lambda错误正则表达式似乎并不尊重这一点.
作为替代方案,您可以使用以下内容:foo(.| \n)*
经过大量研究后,我希望Lambda给出的错误是正确的500错误,提出了以下可行的方法:
在LAMBDA上
为了获得良好的响应,我将返回以下内容:
exports.handler = (event, context, callback) => {
// ..
var someData1 = {
data: {
httpStatusCode: 200,
details: [
{
prodId: "123",
prodName: "Product 1"
},
{
"more": "213",
"moreDetails": "Product 2"
}
]
}
};
return callback(null, someData1);
}
Run Code Online (Sandbox Code Playgroud)
如果响应不好,则返回如下
exports.handler = (event, context, callback) => {
// ..
var someError1 = {
error: {
httpStatusCode: 500,
details: [
{
code: "ProductNotFound",
message: "Product not found in Cart",
description: "Product should be present after checkout, but not found in Cart",
source: "/data/attributes/product"
},
{
code: "PasswordConfirmPasswordDoesntMatch",
message: "Password and password confirmation do not match.",
description: "Password and password confirmation must match for registration to succeed.",
source: "/data/attributes/password",
}
]
}
};
return callback(new Error(JSON.stringify(someError1)));
}
Run Code Online (Sandbox Code Playgroud)
在API网关上
对于GET方法,请说/ res1 / service1的GET:
Through Method Response > Add Response, added 3 responses:
- 200
- 300
- 400
Run Code Online (Sandbox Code Playgroud)
然后,
Through 'Integration Response' > 'Add integration response', create a Regex for 400 errors (client error):
Lambda Error Regex .*"httpStatusCode":.*4.*
'Body Mapping Templates' > Add mapping template as:
Content-Type application/json
Template text box* $input.path('$.errorMessage')
Similarly, create a Regex for 500 errors (server error):
Lambda Error Regex .*"httpStatusCode":.*5.*
'Body Mapping Templates' > Add mapping template as:
Content-Type application/json
Template text box* $input.path('$.errorMessage')
Run Code Online (Sandbox Code Playgroud)
现在,发布/ res1 / service1,点击发布的URL,该URL连接到上述lambda
使用高级REST客户端(或Postman)chrome插件,您会看到正确的http代码,例如服务器错误(500)或400,而不是“ httpStatusCode”中给出的所有请求的200 http响应代码。
在API的“仪表板”的API网关中,我们可以看到如下的http状态代码:
最简单的方法是使用LAMBDA_PROXY集成.使用此方法,您无需将任何特殊转换设置到API网关管道中.
您的返回对象必须类似于下面的代码段:
module.exports.lambdaHandler = (event, context, done) => {
// ...
let response = {
statusCode: 200, // or any other HTTP code
headers: { // optional
"any-http-header" : "my custom header value"
},
body: JSON.stringify(payload) // data returned by the API Gateway endpoint
};
done(null, response); // always return as a success
};
Run Code Online (Sandbox Code Playgroud)
它确实有一些缺点:必须特别注意错误处理,并将lambda函数耦合到API Gateway端点; 那说,如果你真的不打算在其他任何地方使用它,那就不是什么大问题了.
如果您不想使用代理,可以使用此模板:
#set($context.responseOverride.status = $input.path('$.statusCode'))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
56986 次 |
| 最近记录: |