Amazon web services 如何使用RequestTemplates通过HTTP集成修改API网关中的WebSocket请求
我有一个http端点(例如Amazon web services 如何使用RequestTemplates通过HTTP集成修改API网关中的WebSocket请求,amazon-web-services,websocket,amazon-cloudformation,aws-api-gateway,Amazon Web Services,Websocket,Amazon Cloudformation,Aws Api Gateway,我有一个http端点(例如https://sample-sasw.free.beeceptor.com) 以及API网关的websocket API与http集成,如AWS CloudFormation模板中所示 我希望能够连接到websocket: wscat -c wss://nghixzq757.execute-api.eu-west-1.amazonaws.com/production 将$connect发送到我的HTTP端点。 如果可能的话,我想在https://sample-sas
https://sample-sasw.free.beeceptor.com
)
以及API网关的websocket API与http集成,如AWS CloudFormation模板中所示
我希望能够连接到websocket:
wscat -c wss://nghixzq757.execute-api.eu-west-1.amazonaws.com/production
将$connect
发送到我的HTTP端点。
如果可能的话,我想在https://sample-sasw.free.beeceptor.com/connect
在API网关上生成特定的JSON负载,例如
{
"connectionId": "foEf1d_ejoECHeQ=",
"domainName": "nghixzq757.execute-api.eu-west-1.amazonaws.com",
"stage": "production"
}
即使原始$connect
中没有正文。如果这不可能,那也没关系,因为我已经将这些参数作为http头获取了。
一旦连接到websocket,我希望能够通过websocket发送任何有效负载,该负载将在https://sample-sasw.free.beeceptor.com/sendMessage
,但将JSON负载转换为仅获取数据
属性。换句话说,我想要这样的东西:
wscat -c wss://nghixzq757.execute-api.eu-west-1.amazonaws.com/production
Connected (press CTRL+C to quit)
> {'action': 'sendMessage', 'data': '{'foo': 'bar'}'}
< OK!!
我不能让它工作。我花了好几个小时试图找到关于如何使用CloudFormation YML的RequestTemplates
和TemplateSelectionExpression
的好例子,以理解它或让一个简单的例子起作用
我得到了一些结果
$ wscat -c wss://nghixzq757.execute-api.eu-west-1.amazonaws.com/production
Connected (press CTRL+C to quit)
> {'action': 'sendMessage', 'data': {'foo': 'bar'}}
< {"message": "Internal server error", "connectionId":"foEf1d_ejoECHeQ=", "requestId":"foFlwEtkjoEFkWw="}
> {'action': 'sendMessage', 'data': ''}
< {"message": "Internal server error", "connectionId":"foEf1d_ejoECHeQ=", "requestId":"foFlwEtkjoEFkWw="}
$ wscat -c wss://nghixzq757.execute-api.eu-west-1.amazonaws.com/production
Connected (press CTRL+C to quit)
> {'action': 'sendMessage', 'data': {'foo': 'bar'}}
< {"message": "Internal server error", "connectionId":"foEf1d_ejoECHeQ=", "requestId":"foFlwEtkjoEFkWw="}
> {'action': 'sendMessage', 'data': ''}
< {"message": "Internal server error", "connectionId":"foEf1d_ejoECHeQ=", "requestId":"foFlwEtkjoEFkWw="}
AWSTemplateFormatVersion: 2010-09-09
Description: Sample API Gateway with Websocket
Parameters:
hostname:
Type: String
Description: The hostname to use in http integration
Default: sample-sasw.free.beeceptor.com
Resources:
websocketApiGateway:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: sample-websocket-gateway
Description: Api Gateway for websocket
ProtocolType: WEBSOCKET
RouteSelectionExpression: $request.body.action
connectRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref websocketApiGateway
RouteKey: $connect
AuthorizationType: NONE
OperationName: ConnectRoute
RouteResponseSelectionExpression: $default
Target: !Join
- /
- - integrations
- !Ref connectIntegration
connectIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref websocketApiGateway
Description: Websocket $connect integration
ConnectionType: INTERNET
IntegrationType: HTTP_PROXY # no need to transform payload in $connect
IntegrationMethod: POST
IntegrationUri: !Sub https://${hostname}/connect
RequestParameters:
"integration.request.header.domainName": "context.domainName"
"integration.request.header.stage": "context.stage"
"integration.request.header.connectionId": "context.connectionId"
PayloadFormatVersion: 1.0
connectRouteResponse:
Type: AWS::ApiGatewayV2::RouteResponse
Properties:
ApiId: !Ref websocketApiGateway
RouteId: !Ref connectRoute
RouteResponseKey: $default
sendMessageRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref websocketApiGateway
RouteKey: sendMessage
AuthorizationType: NONE
OperationName: SendMessageRoute
RouteResponseSelectionExpression: $default
Target: !Join
- /
- - integrations
- !Ref sendMessageIntegration
sendMessageIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref websocketApiGateway
Description: Websocket sendMessage integration
IntegrationType: HTTP
IntegrationMethod: POST
IntegrationUri: !Sub https://${hostname}/sendmessage
RequestParameters:
"integration.request.header.domainName": "context.domainName"
"integration.request.header.stage": "context.stage"
"integration.request.header.connectionId": "context.connectionId"
RequestTemplates: # HOW DOES THIS WORK??
"connectionId": "$context.connectionId"
# "body": "$input.body"
TemplateSelectionExpression: \$default # match all incoming requests
PayloadFormatVersion: 1.0
sendRouteResponse:
Type: AWS::ApiGatewayV2::RouteResponse
Properties:
ApiId: !Ref websocketApiGateway
RouteId: !Ref sendMessageRoute
RouteResponseKey: $default
websocketStage:
Type: AWS::ApiGatewayV2::Stage
Properties:
StageName: production
Description: Production stage
AutoDeploy: true
ApiId: !Ref websocketApiGateway
Outputs:
websocketUri:
Description: Websocket root URL
Value: !Sub wss://${websocketApiGateway}.execute-api.${AWS::Region}.amazonaws.com/${websocketStage}