简体   繁体   English

AWS API Gatewat WebSocket:集成后端中缺少转换后请求的请求模板正文

[英]AWS API Gatewat WebSocket: Request Templates body of request after transformations is missing in integration backend

I am building my app on AWS and yy app uses websocket like this:我正在 AWS 上构建我的应用程序,yy 应用程序使用 websocket,如下所示:

Frontend WebSocket client ---> AWS API Gateway Websocket API ----> Backend in EC2 instance.前端 WebSocket 客户端 ---> AWS API 网关 Websocket ZDB974238714CA8DE634A7CE1DZFZ 实例在 EC23A 实例中。

Now, in order to let my backend Express code know how to send message to a particular client, I have let it know the connectionId of a websocket client / a user.现在,为了让我的后端 Express 代码知道如何向特定客户端发送消息,我让它知道 websocket 客户端/用户的connectionId I am following these two answers: https://stackoverflow.com/a/59220644/3703783我正在关注这两个答案: https://stackoverflow.com/a/59220644/3703783

https://stackoverflow.com/a/65112135/3703783 https://stackoverflow.com/a/65112135/3703783

which have explained very clearly.这已经解释得很清楚了。

Below is my configuration in AWS API Gateway WebSocket API:下面是我在 AWS API 网关 WebSocket API 中的配置:

在此处输入图像描述

What I did was using Request Template, matching all incoming requests, to transform the content which will be sent to my integration endpoint as the body of the request.我所做的是使用请求模板,匹配所有传入的请求,来转换将作为请求正文发送到我的集成端点的内容。 Eventually I want to keep the original request, while adding attributes (like Connection Id) on top of it.最终我想保留原始请求,同时在其上添加属性(如连接 ID)。 For testing purpose, I set the following template:出于测试目的,我设置了以下模板:

{
    "myConnectionId": "$context.connectionId",
    "body": "$context"
}

This worked and I can check in AWS CloudWatch that the request body after transform is这有效,我可以在 AWS CloudWatch 中检查转换后的请求正文是

{
   "myConnectionId":"MFEdof95tjMCK0w=",
   "body":"{routeKey=$connect, disconnectStatusCode=null, messageId=null, eventType=CONNECT, extendedRequestId=MFEdoFJPtjMF64Q=, requestTime=17/Jan/2022:07:29:01 +0000, messageDirection=IN, disconnectReason=null, stage=production, connectedAt=1642404541417, requestTimeEpoch=1642404541418, identity={cognitoIdentityPoolId=null, cognitoIdentityId=null, principalOrgId=null, cognitoAuthenticationType=null, userArn=null, userAgent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36, accountId=null, caller=null, sourceIp=219.102.102.145, accessKey=null, cognitoAuthenticationProvider=null, user=null}, requestId=MFEdoFJPtjMF64Q=, domainName=123.execute-api.ap-northeast-1.amazonaws.com, connectionId=MFEdof95tjMCK0w=, apiId=hd5zymklr8}"
}

在此处输入图像描述

However, in my Express backend running in EC2 instance, even though the endpoint is triggered, the request body is empty and there is no place to find myConnectionId in it.但是,在我在 EC2 实例中运行的 Express 后端中,即使触发了端点,请求正文也是空的,并且在其中找不到myConnectionId的地方。

Backend: NodeJS / ExpressJS, and in index.ts :后端:NodeJS / ExpressJS,在index.ts中:

  app.get('/connect', function(_req, res) {
    logger.info(`/connect _req: ${Object.keys(_req)}`);
    logger.info(`/connect _req.query: ${JSON.stringify(_req.query)}`);
    logger.info(`/connect _req.params: ${JSON.stringify(_req.params)}`);
    logger.info(`/connect _req.body: ${JSON.stringify(_req.body)}`);
    logger.info(`/connect _req.headers: ${JSON.stringify(_req.headers)}`);
    res.send('/connect hahaha success');
  });

Log output:日志 output:

2022-Jan-17 05:05:00:50  info: /connect _req: _readableState,_events,_eventsCount,_maxListeners,socket,httpVersionMajor,httpVersionMinor,httpVersion,complete,rawHeaders,rawTrailers,aborted,upgrade,url,method,statusCode,statusMessage,client,_consuming,_dumped,next,baseUrl,originalUrl,_parsedUrl,params,query,res,_startAt,_startTime,_remoteAddress,body,_parsedOriginalUrl,route
2022-Jan-17 05:05:00:50  info: /connect _req.query: {}
2022-Jan-17 05:05:00:50  info: /connect _req.params: {}
2022-Jan-17 05:05:00:50  info: /connect _req.body: {}
2022-Jan-17 05:05:00:50  info: /connect _req.headers: {"x-amzn-apigateway-api-id":"hd5zymklr8","x-amzn-trace-id":"Root=1-61e5232c-626a05ff264650183a73c98a","user-agent":"AmazonAPIGateway_hd5zymklr8","content-type":"application/json","accept":"application/json","host":"NLB-docloud-internal-ea0692d1e2c8186c.elb.ap-northeast-1.amazonaws.com","connection":"Keep-Alive"}

The request is indeed sent to the endpoint, but why is the request body empty?请求确实发送到了端点,但是为什么请求体是空的?

How is the content lost?内容如何丢失?

I have done some research on this.我对此做了一些研究。

As it has been discussed in this post: AWS API Gateway Websockets -- where is the connectionID?正如这篇文章中所讨论的那样: AWS API 网关 Websockets——connectionID 在哪里? , the accepted answers (the solution I was trying in my question above) are assuming your are using Lambda as the backend integration. ,接受的答案(我在上面的问题中尝试的解决方案)假设您使用 Lambda 作为后端集成。

However, I am using Express JS running in EC2 instance and VPC Link.但是,我使用的是在 EC2 实例和 VPC Link 中运行的 Express JS。

In my case, the issue actually is solved by one of the upvoted answers (but not the accepted one): https://stackoverflow.com/a/65639742/3703783 .就我而言,这个问题实际上是通过一个赞成的答案(但不是接受的答案)解决的: https://stackoverflow.com/a/65639742/3703783

The official documentation is here: Setting up data mapping for WebSocket APIs .官方文档在这里: 为 WebSocket API 设置数据映射

Update更新

I also found that in my original question, instead of doing我还发现在我原来的问题中,而不是做

{
    "myConnectionId": "$context.connectionId",
    "body": "$context"
}

I should simply do:我应该简单地做:

{
  "integration.request.header.connectionId":"$context.connectionId",
}

and this will fix the issue.这将解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM