当通过 SAM 使用 HttpApi 时,OpenApi 定义是唯一的真理点吗?
When using HttpApi via SAM is the OpenApi definition the single point of truth?
我花了一天时间来跟上 SAM 的速度,尤其是 HttpApi,但遇到了瓶颈。这是我想要实现的(梦想):
- 在 Open API 3(合约)
中创建一个 REST API
- 将 api.yaml 传递给 HttpApi 并让它为 api
生成所有样板文件
- 现在我的 api 文档和我的 api 路线始终相同(根据合同),感觉很温暖
- 将 Open API 规范交给前端人员和后端人员,让他们在中间很好地相遇
我很确定它应该是这样工作的。但这让我感到困惑。我正在将集成添加到我的 api.yaml 例如:
get:
summary: get item
tags:
- Items
responses:
'200':
description: Item returned successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ItemResource'
'404':
$ref: '#/components/responses/NotFound'
x-amazon-apigateway-integration:
payloadFormatVersion: "2.0"
type: "aws_proxy"
httpMethod: "POST"
uri:
Fn::GetAtt [GetItemFunction, Arn]
connectionType: "INTERNET"
现在我期待通过这个 HttpApi 将我的 OpenApi 文件中的路由与我在集成“GetItemFunction”中指向的 Lambda 连接起来。所以我可以像这样定义我的 Lambda:
GetItemFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: get-item.handler
Runtime: nodejs12.x
但这似乎没有按预期设置路由(我正在使用“sam local start-api”进行测试)。为了让它工作,我需要这样做:
GetItemFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: get-item.handler
Runtime: nodejs12.x
Events:
GetAllItems:
Type: HttpApi
Properties:
ApiId: !Ref MyHttpApi
Path: /items/{id}
Method: get
这行得通,但现在我在 template.yaml 文件而不是 api.yaml 文件中定义路由,这对我的用例来说无法达到目的。无论我是否在 api.yaml 中添加 'x-amazon-apigateway-integration',它的行为似乎也完全相同。
我确定我在这里遗漏了一些东西,如果有人能让我走上正确的道路,我将不胜感激!
当您使用事件源在 SAM 中声明连接时,SAM 会创建权限。如果您不使用事件源,则 SAM 不会构建权限,并且 API 网关无权调用 Lambda 函数。如果您想手动构建它,请在 SAM 模板中创建一个角色。这是一个工作示例(简化为一个模板):
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: OpenAPI test
Resources:
MyHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
DefinitionBody:
openapi: "3.0.1"
info:
title: "OpenAPI test"
paths:
/:
get:
responses:
default:
description: Item returned successfully
x-amazon-apigateway-integration:
payloadFormatVersion: "2.0"
credentials: !GetAtt MyHttpApiRole.Arn
type: "aws_proxy"
httpMethod: "POST"
uri: !GetAtt GetItemFunction.Arn
connectionType: "INTERNET"
x-amazon-apigateway-importexport-version: "1.0"
MyHttpApiRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "apigateway.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
- PolicyName: ApiDirectWriteToSQS
PolicyDocument:
Version: '2012-10-17'
Statement:
Action:
- lambda:InvokeFunction
Effect: Allow
Resource:
- !GetAtt GetItemFunction.Arn
GetItemFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.handler
Runtime: nodejs12.x
我花了一天时间来跟上 SAM 的速度,尤其是 HttpApi,但遇到了瓶颈。这是我想要实现的(梦想):
- 在 Open API 3(合约) 中创建一个 REST API
- 将 api.yaml 传递给 HttpApi 并让它为 api 生成所有样板文件
- 现在我的 api 文档和我的 api 路线始终相同(根据合同),感觉很温暖
- 将 Open API 规范交给前端人员和后端人员,让他们在中间很好地相遇
我很确定它应该是这样工作的。但这让我感到困惑。我正在将集成添加到我的 api.yaml 例如:
get:
summary: get item
tags:
- Items
responses:
'200':
description: Item returned successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ItemResource'
'404':
$ref: '#/components/responses/NotFound'
x-amazon-apigateway-integration:
payloadFormatVersion: "2.0"
type: "aws_proxy"
httpMethod: "POST"
uri:
Fn::GetAtt [GetItemFunction, Arn]
connectionType: "INTERNET"
现在我期待通过这个 HttpApi 将我的 OpenApi 文件中的路由与我在集成“GetItemFunction”中指向的 Lambda 连接起来。所以我可以像这样定义我的 Lambda:
GetItemFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: get-item.handler
Runtime: nodejs12.x
但这似乎没有按预期设置路由(我正在使用“sam local start-api”进行测试)。为了让它工作,我需要这样做:
GetItemFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: get-item.handler
Runtime: nodejs12.x
Events:
GetAllItems:
Type: HttpApi
Properties:
ApiId: !Ref MyHttpApi
Path: /items/{id}
Method: get
这行得通,但现在我在 template.yaml 文件而不是 api.yaml 文件中定义路由,这对我的用例来说无法达到目的。无论我是否在 api.yaml 中添加 'x-amazon-apigateway-integration',它的行为似乎也完全相同。
我确定我在这里遗漏了一些东西,如果有人能让我走上正确的道路,我将不胜感激!
当您使用事件源在 SAM 中声明连接时,SAM 会创建权限。如果您不使用事件源,则 SAM 不会构建权限,并且 API 网关无权调用 Lambda 函数。如果您想手动构建它,请在 SAM 模板中创建一个角色。这是一个工作示例(简化为一个模板):
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: OpenAPI test
Resources:
MyHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
DefinitionBody:
openapi: "3.0.1"
info:
title: "OpenAPI test"
paths:
/:
get:
responses:
default:
description: Item returned successfully
x-amazon-apigateway-integration:
payloadFormatVersion: "2.0"
credentials: !GetAtt MyHttpApiRole.Arn
type: "aws_proxy"
httpMethod: "POST"
uri: !GetAtt GetItemFunction.Arn
connectionType: "INTERNET"
x-amazon-apigateway-importexport-version: "1.0"
MyHttpApiRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "apigateway.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
- PolicyName: ApiDirectWriteToSQS
PolicyDocument:
Version: '2012-10-17'
Statement:
Action:
- lambda:InvokeFunction
Effect: Allow
Resource:
- !GetAtt GetItemFunction.Arn
GetItemFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.handler
Runtime: nodejs12.x