在AWS AppSync中,我该如何记录和调试Velocity模板语言(VTL)?

33
  1. 除了发送查询变异以进行调试和日志记录之外,是否有任何简单的方法来记录或调试来自请求映射模板和响应映射模板的VTL?

  2. 此外,是否有任何游乐场可以像在Web控制台中使用JavaScript一样检查和玩耍VTL?

  3. 我们可以离线使用AWS AppSync并检查VTL中编写的所有内容是否按预期工作吗?


3
  1. 感谢您提出此事。我是AWS AppSync团队的一员,将代表您在内部跟进功能请求。
  2. 您可以通过AppSync控制台使用模拟/测试数据来测试您的映射模板。
  3. 方法2不涉及与数据源的往返,测试数据用于验证您的模板。
- Shankar Raju
感谢@ShankarRaju。此外,文档还不够完善。如果您能改进它们,那就请尽力吧。这是我的相关问题 https://twitter.com/deadcoder0904/status/997431929346707456 - deadcoder0904
我们会将您的反馈传达给团队。感谢您的贡献。 - Shankar Raju
17
这种模板引擎引入一种新语言的方式是低劣的。为什么不使用像nodejs、python这样广泛使用的编程语言呢?毕竟我们只是处理数据对象。在我的25多年经验中,我从未见过任何人使用VTL,也没有必要使用它。 - Kannaiyan
7个回答

21

一个非常不好的记录和调试方式是在响应映射中使用验证(validate)

$util.validate(false, $util.time.nowISO8601().substring(0, 10) )

7
AWS发布了一个半成品产品到生产环境中。 - Kannaiyan
57
调试AppSync VTL真是一场噩梦 :-( - SaidAkh
4
在使用 AppSync 之前,为什么我没有发现上面的两条评论呢?请问这是为什么?请帮我翻译一下。 - Snowfish
在AppSync中记录/调试VTL仍然是唯一/最佳的方式吗? - sumek
2
AWS发布了Amplify的更新,其中包含一些本地VTL调试支持。https://aws.amazon.com/blogs/mobile/amplify-framework-local-mocking/ 但总体来说,调试VTL仍然是一场噩梦。 - Rob Boerman
显示剩余3条评论

16

这是我在我的VTL解析器中记录值的方法:

在您的请求或响应模板中添加"$util.error"语句,然后进行graphql调用。

例如,我想查看传递给我的解析器作为输入的参数是什么,因此我在模板开头添加了$util.error语句。 因此,我的模板现在如下:

$util.error("Test Error", $util.toJson($ctx))
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.arguments.user.id)
    },
    "attributeValues": {
        "name": $util.dynamodb.toDynamoDBJson($ctx.arguments.user.name)
    }
}

然后从 AWS AppSync 控制台的“查询”部分,我运行了以下变更操作:

mutation MyMutation {
  addUser(user: {id: "002", name:"Rick Sanchez"}) {
    id
    name
  }
}

这显示了我的解析器的日志结果如下:

{
  "data": null,
  "errors": [
    {
      "path": [
        "addUser"
      ],
      "data": null,
      "errorType": "{\"arguments\":{\"user\":{\"id\":\"002\",\"name\":\"Rick Sanchez\"}},\"identity\":null,\"source\":null,\"result\":null,\"request\":{\"headers\":{\"x-forwarded-for\":\"112.133.236.59, 130.176.75.151\",\"sec-ch-ua-mobile\":\"?0\",\"cloudfront-viewer-country\":\"IN\",\"cloudfront-is-tablet-viewer\":\"false\",\"via\":\"2.0 a691085135305af276cea0859fd6b129.cloudfront.net (CloudFront)\",\"cloudfront-forwarded-proto\":\"https\",\"origin\":\"https://console.aws.amazon.com\",\"content-length\":\"223\",\"accept-language\":\"en-GB,en;q=0.9,en-US;q=0.8\",\"host\":\"raxua52myfaotgiqzkto2rzqdy.appsync-api.us-east-1.amazonaws.com\",\"x-forwarded-proto\":\"https\",\"user-agent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66\",\"accept\":\"*/*\",\"cloudfront-is-mobile-viewer\":\"false\",\"cloudfront-is-smarttv-viewer\":\"false\",\"accept-encoding\":\"gzip, deflate, br\",\"referer\":\"https://console.aws.amazon.com/\",\"x-api-key\":\"api-key-has-been-edited-out\",\"content-type\":\"application/json\",\"sec-fetch-mode\":\"cors\",\"x-amz-cf-id\":\"AvTMLvtxRq9M8J8XntvkDj322SZa06Fjtyhpf_fSXd-GmHs2UeomDg==\",\"x-amzn-trace-id\":\"Root=1-5fee036a-13f9ff472ba6a1211d499b8b\",\"sec-fetch-dest\":\"empty\",\"x-amz-user-agent\":\"AWS-Console-AppSync/\",\"cloudfront-is-desktop-viewer\":\"true\",\"sec-fetch-site\":\"cross-site\",\"sec-ch-ua\":\"\\\"Chromium\\\";v=\\\"87\\\", \\\" Not;A Brand\\\";v=\\\"99\\\", \\\"Microsoft Edge\\\";v=\\\"87\\\"\",\"x-forwarded-port\":\"443\"}},\"info\":{\"fieldName\":\"addUser\",\"parentTypeName\":\"Mutation\",\"variables\":{}},\"error\":null,\"prev\":null,\"stash\":{},\"outErrors\":[]}",
      "errorInfo": null,
      "locations": [
        {
          "line": 9,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Test Error"
    }
  ]
}

5
我觉得这很有用,所以我点了赞。我将其用于更好地与错误对象对齐,提高可读性:$util.error("DEBUG", 'REQUEST', null, $postBody)这会生成以下响应:"message": "DEBUG", "errorType": "REQUEST", "data": null, "errorInfo": "{\"postBodyStuff\":\"whatever\"}" - ConorLuddy
2
打印 context 和这些 info 字段是有帮助的:$util.error($util.toJson($context), $util.toJson($context.info.selectionSetList), null, $util.toJson($context.info.selectionSetGraphQL)) - Santiago

8

2
现在应该接受这个答案。很高兴他们添加了一个实际的日志记录工具 - 谢谢! - ckifer

3
你的三个问题的答案如下:
  1. 为了单元测试请求/响应映射模板,你可以使用这篇博客文章中描述的方法(https://mechanicalrock.github.io/2020/04/27/ensuring-resolvers-aren't-rejected.html)。
  2. AWS AppSync控制台提供了一个VTL实验场,你可以在其中编辑和测试解析器的VTL。
  3. Amplify框架具有模拟功能,可以模拟AppSync、AppSync VTL环境和DynamoDB(使用DynamoDB Local)。这将允许你在本地执行端到端测试。

1

当我意识到调试VTL有多么痛苦时,我创建了一个lambda(nodejs),记录了我的VTL模板的内容。

// my nodejs based debug lambda -- very basic
exports.handler = (event, context, callback) => {
  const origin = context.request || 'oops';

  if (context && context.prev) {
    console.log('--------with context----------------');
    console.log({ prev: context.prev.result, context, origin });
    console.log({ stash: context.stash });
    console.log('--------END: with context----------------');

    callback(null, context.prev.result);
  }

  console.log('inside - LOGGING_DEBUGGER');
  console.log({ event, context: context || null, origin });

  callback(null, event);
};

这个 Lambda 函数帮助我解决了管道处理器中的很多问题。然而,我忘记了自己是直接使用它还是在请求和响应模板中使用它。
要使用它,我在其他管道函数中将想要调试的值放入 $ctx.stash 中。然后,在我的管道中,在此步骤之后添加了“debugger”函数——以防出现问题,导致我的管道在发生致命错误之前崩溃。

1

这个问题已经有一段时间了,自问出现以来发生了很多变化。我会尽力提供更现代的见解。

首先,值得一提的是,AppSync 现在支持 JavaScript 解析器。这对开发者体验来说是一个重要的变革。我强烈推荐使用。

回答原始问题:

  1. VTL 和 JS 解析器现在都支持日志记录。

对于 JS 解析器,您可以简单地使用 console.log()。记录的数据将显示在 CloudWatch 中。

  1. 现在可以测试解析器。

aws CLI 自带一个命令,允许您测试解析器,而无需部署和调用查询。请参阅文档

  1. 正如其他人所提到的,有一些解决方案可用于本地测试AppSync(即Amplify CLI)。然而,我不建议这样做。相反,我更喜欢直接在云端进行测试。这样可以更加确信它能按预期工作。不幸的是,这仍然有点麻烦(因为部署时间),但希望随着CDK热交换、SAM加速等功能的推出,这种情况会有所改善。

您还可以使用评估命令来编写单元/集成测试

除了上述所有“内置”解决方案外,我还创建了一个名为GraphBolt的应用程序,旨在改善AWS AppSync DX并解决此处提到的一些痛点。


0

CloudWatch日志工具中检查$util.log.info(Object) : Void

附注:您需要打开Amazon CloudWatch Logs的日志记录,并将字段解析器日志级别设置为ALL,更多详细信息请参见此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接