Chr*_*ris 36 api amazon-web-services aws-lambda aws-api-gateway
我有一个AWS api代理lamba函数.我目前使用不同的端点和单独的lambda函数:
api.com/getData --> getData
api.com/addData --> addData
api.com/signUp --> signUp
Run Code Online (Sandbox Code Playgroud)
管理所有端点和功能的过程变得很麻烦.当我将一个端点用于一个lambda函数时,是否有任何缺点,该函数根据查询字符串决定做什么?
api.com/exec&func=getData --> exec --> if(params.func === 'getData') { ... }
Run Code Online (Sandbox Code Playgroud)
Dav*_*ple 40
将多个方法映射到单个lambda函数是完全有效的,并且今天许多人正在使用这种方法,而不是为每个离散方法创建api网关资源和lambda函数.
您可以考虑将所有请求代理到单个函数.请查看以下有关创建API网关=> Lambda代理集成的文档:http: //docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html
他们的榜样很棒.请求如下:
POST /testStage/hello/world?name=me HTTP/1.1
Host: gy415nuibc.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
headerName: headerValue
{
"a": 1
}
Run Code Online (Sandbox Code Playgroud)
最终将以下事件数据发送到您的AWS Lambda函数:
{
"message": "Hello me!",
"input": {
"resource": "/{proxy+}",
"path": "/hello/world",
"httpMethod": "POST",
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"cache-control": "no-cache",
"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",
"headerName": "headerValue",
"Host": "gy415nuibc.execute-api.us-east-1.amazonaws.com",
"Postman-Token": "9f583ef0-ed83-4a38-aef3-eb9ce3f7a57f",
"User-Agent": "PostmanRuntime/2.4.5",
"Via": "1.1 d98420743a69852491bbdea73f7680bd.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "pn-PWIJc6thYnZm5P0NMgOUglL1DYtl0gdeJky8tqsg8iS_sgsKD1A==",
"X-Forwarded-For": "54.240.196.186, 54.182.214.83",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"queryStringParameters": {
"name": "me"
},
"pathParameters": {
"proxy": "hello/world"
},
"stageVariables": {
"stageVariableName": "stageVariableValue"
},
"requestContext": {
"accountId": "12345678912",
"resourceId": "roq9wj",
"stage": "testStage",
"requestId": "deef4878-7910-11e6-8f14-25afc3e9ae33",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": null,
"sourceIp": "192.168.196.186",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "PostmanRuntime/2.4.5",
"user": null
},
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "gy415nuibc"
},
"body": "{\r\n\t\"a\": 1\r\n}",
"isBase64Encoded": false
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以访问所有标题,url参数,正文等,您可以使用它来在单个Lambda函数中以不同方式处理请求(基本上实现您自己的路由).
作为一种观点,我看到了这种方法的一些优点和缺点.其中许多取决于您的具体用例:
Pål*_*ver 19
AWS 官方博文“组织大型无服务器应用程序的最佳实践”中也讨论了类似的场景中也讨论了类似的场景。
\n一般建议是将“整体 lambda”拆分为单独的 lambda,并将路由移至 API 网关。
\n这是博客中关于“整体 lambda”方法的描述:
\n\n\n\n这种方法通常是不必要的,\xe2\x80\x99s 通常最好利用 API Gateway 中可用的本机路由功能。\n...\nAPI Gateway 还能够验证参数,从而减少\n需求用于使用自定义代码检查参数。它还可以提供针对未经授权的访问的保护,以及一系列更适合在服务级别处理的其他功能。
\n
对此
\n\n小智 13
我一直在使用Lambda-API网关构建5~6个微服务,经历了几次尝试失败并取得了成功.
简而言之,根据我的经验,最好只使用一个APIGateway通配符映射将所有API调用委托给lambda,例如
/api/{+proxy} -> Lambda
Run Code Online (Sandbox Code Playgroud)
如果你曾经使用像葡萄这样的任何框架你知道在制作API时,
"中间件",
"全局异常处理",
"级联路由",
"参数验证"
等功能真的很重要.随着API的增长,几乎不可能使用API网关映射管理所有路由,也不支持API网关支持这些功能.
更进一步,为开发或部署打破每个端点的lambda实际上并不是真的.
从你的例子来看,
api.com/getData --> getData
api.com/addData --> addData
api.com/signUp --> signUp
Run Code Online (Sandbox Code Playgroud)
想象你有数据ORM,用户身份验证逻辑,通用视图文件(如data.erb)..然后你将如何分享?
你可能会破坏,
api/auth/{+proxy} -> AuthServiceLambda
api/data/{+proxy} -> DataServiceLambda
Run Code Online (Sandbox Code Playgroud)
但不像"每个端点".您可以查找有关如何拆分服务的微服务概念和最佳实践
像功能的web框架,结帐这个因为我需要这在我公司拉姆达我们刚刚建立的Web框架.
我想评论只是为Dave Maple的答案添加几点,但我还没有足够的声望点,所以我会在这里添加评论.
我开始沿着指向一个Lambda函数的多个端点的路径前进,该函数可以通过访问Event的'resource'属性来处理每个端点.在尝试之后,我现在将它们分成单独的函数,原因是Dave建议加上:
小智 5
将 API 请求映射到 AWS 中的 Lambda 的责任是通过网关的 API 规范来处理的。
URL 路径和 HTTP 方法的映射以及数据验证应该留给网关。还有权限和 API 范围的问题;您将无法以正常方式利用 API 范围和 IAM 权限级别。
就编码而言,在 Lambda 处理程序内部复制此机制是一种反模式。沿着这条路线走下去,很快就会得到类似于 Node Express 服务器的路由,而不是 Lambda 函数。
在 API Gateway 后面设置了 50 多个 Lambda 后,我可以说函数处理程序应尽可能保留为转储,从而使它们能够独立于调用它们的上下文而重复使用。
| 归档时间: |
|
| 查看次数: |
20333 次 |
| 最近记录: |