AWS API网关WebSocket:集成后端缺少转换后请求的请求模板正文 [英] AWS API Gatewat WebSocket: Request Templates body of request after transformations is missing in integration backend

查看:39
本文介绍了AWS API网关WebSocket:集成后端缺少转换后请求的请求模板正文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在AWS上构建我的应用程序,我的应用程序使用WebSocket,如下所示:

EC2实例中的前端WebSocket客户端->;AWS API网关WebSocket API->;后端。

现在,为了让我的后端Express代码知道如何向特定客户端发送消息,我让它知道a WebSocket客户端/a用户的connectionId。我遵循这两个答案:

说明非常清楚。

下面是我在AWS API网关WebSocket API中的配置:

我所做的是使用请求模板匹配所有传入的请求,以转换将作为请求主体发送到我的集成端点的内容。 最终,我希望保留原始请求,同时在其上面添加属性(如连接ID)。 出于测试目的,我设置了以下模板:

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

这起作用了,我可以在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}"
}

但是,在EC2实例中运行的My Express后端中,即使触发了终结点,请求正文也是空的,并且在其中找不到myConnectionId

后端: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');
  });

日志输出:

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"}

请求确实发送到终结点,但为什么请求正文为空?

内容是如何丢失的?

推荐答案

我对此做了一些研究。

正如本文所讨论的:AWS API Gateway Websockets -- where is the connectionID?,公认的答案(我在上面问题中尝试的解决方案)假定您使用Lambda作为后端集成。

不过,我使用的是在EC2实例和VPC链路中运行的Express JS。

在我的案例中,问题实际上是由一个被支持的答案(但不是被接受的答案)解决的:https://stackoverflow.com/a/65639742/3703783

官方文档在这里:Setting up data mapping for WebSocket APIs

更新

上述方法会将connectionId添加到集成请求的头部,但仅有connectionId是不够的-我们还需要用户名等信息,以便后端能够知道在向特定用户发送消息时使用哪个connectionId。这样就可以了:

aws apigatewayv2 update-integration 
--integration-id xxx 
--api-id xxx 
--request-parameters 'integration.request.header.userinfo'='route.request.body' 

另外,我还发现在我的原始问题中,没有做

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

我应该简单地做:

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

这会将connectionId添加到请求标头。

这篇关于AWS API网关WebSocket:集成后端缺少转换后请求的请求模板正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆