我正在尝试使用SAM模板设置AWS API网关。在将传入的事件数据插入数据库之前,我想使用定义的模型来验证传入的事件数据,这是通过接口完成的,但是我需要能够通过代码来完成。不幸的是,我在将代码部署到AWS时遇到了各种各样的错误,并且在本地运行它并不能验证传入的数据。这是我的模板。yaml文件:
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
company
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Models:
company:
$schema: 'http://json-schema.org/draft-04/schema#'
type: object
properties:
name:
type: string
email:
type: string
website:
type: string
phone:
type: string
required:
- name
- phone
PostCompanyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/functions
Handler: company.postCompany
Runtime: nodejs14.x
Architectures:
- x86_64
Events:
Company:
Type: Api
Properties:
Path: /company
Method: post
RestApiId: !Ref ApiGatewayApi
RequestModel:
Model: !Ref company
Required: true
ValidateBody: true
Metadata:
BuildMethod: esbuild
BuildProperties:
Minify: true
Target: "es2020"
Sourcemap: true
EntryPoints:
- company.ts
这段代码在没有验证的情况下工作良好(因为它可以成功创建公司条目),但是当我试图引用公司模型进行验证时,我在sam deploy
Error: Failed to create changeset for the stack: companyAPI, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state: For expression "Status" we matched expected path: "FAILED" Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [PostCompanyFunction] is invalid. Event with id [Company] is invalid. Unable to set RequestModel [{u'Ref': u'company'}] on API method [post] for path [/company] because the related API does not contain valid Models.
我已经尝试从请求模型的模型属性中删除!Ref
,但这显示了这个错误:
Error: Failed to create changeset for the stack: companyAPI, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state: For expression "Status" we matched expected path: "FAILED" Status: FAILED. Reason: Unresolved resource dependencies [ServerlessRestApi] in the Outputs block of the template
我已经阅读了我能找到的关于这方面的几乎所有资源,但仍然没有能够使它工作。如有任何帮助,不胜感激。
目前使用的资源:
AWS SAM -通过SAM模板在API网关方法中执行请求验证
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html sam-api-models
如何在AWS::Serverless::Api的AWS SAM模板中添加请求验证器?
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-requestmodel.html
https://github.com/aws/aws-sam-cli/issues/364
我还发现了添加了RequestModel属性的请求和PR,但仍然没有运气使其工作。
好了,我想我终于弄明白了。ApiGatewayApi
是一个保留字,所以我必须在资源中重新命名它。您还必须在输出模板中使用该资源名。下面是根据定义的模型检查请求体的最后一个模板。同样值得注意的是,这在使用sam local start-api
运行时不起作用,因为模型驻留在API Gateway中,而不是在docker容器中启动。但是,当您运行sam deploy
时,这确实有效。
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
company-service
Resources:
CompanyRestApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Models:
companyModel:
type: object
required:
- name
- phone
properties:
name:
type: string
email:
type: string
website:
type: string
phone:
type: string
# Company Endpoints
PostCompanyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/functions
Handler: company.postCompany
Runtime: nodejs14.x
Architectures:
- x86_64
Events:
Company:
Type: Api
Properties:
Path: /company
Method: post
RestApiId: !Ref CompanyRestApi
RequestModel:
Model: companyModel
Required: true
ValidateBody: true
Metadata:
BuildMethod: esbuild
BuildProperties:
Minify: true
Target: "es2020"
Sourcemap: true
EntryPoints:
- company.ts
Outputs:
# Company Outputs
PostCompanyFunctionApi:
Description: "API Gateway endpoint URL for Prod stage for PostCompaniesFunction"
Value: !Sub "https://${CompanyRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/company"
PutCompanyFunctionApi:
Description: "API Gateway endpoint URL for Prod stage for