新 Microsoft.Azure.Cosmos SDK 中的 CompositeToken
CompositeToken in new Microsoft.Azure.Cosmos SDK
我正在从 Microsoft.Azure.DocumentDB.Core SDK 迁移到新的 Microsoft.Azure.Cosmos SDK(版本 3.2)。
较旧的 SDK returns ResponseContinuation 中的 ContinuationToken 属性 看起来像这样:
+RID:knNRALdSjOBBAQAAAAAAAA==#RT:1#TRC:10#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMjlVMjg7MTQ7MTkvMTE6ODgyOFsA#ISV:2#IEO:65536#FPC:AgEAAAAKAAyBIwBA3L8PAAQ=
新的 SDK returns 它在 ContinuationToken 属性 中作为一个 JSON 字符串表示一个 "CompositeToken" 对象并且看起来像这样:
[{"compositeToken":{"token":"+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMzhVMTE7NTc7NDUvNjc2NDozNFsA#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=","range":{"min":"","max":"FF"}},"orderByItems":[{"item":"2019-09-27T00:46:34.5653923Z"}],"rid":"xS0oAMD5rWYLAAAAAAAAAA==","skipCount":0,"filter":null}]
当我只取出令牌时:
+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMzhVMTE7NTc7NDUvNjc2NDozNFsA#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=
我收到以下错误:
Invalid JSON in continuation token
+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:z9path31ttPskBzzyJFdBTQ0NDQ0AA==#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=
for OrderBy~Context, exception: Unexpected character encountered while
parsing value: +. Path '', line 0, position 0.
但是如果我传入整个复合令牌,它就可以工作。我有点困惑,因为这两个 SDK 都只是使用 CosmosDB 服务的 warppers 那么为什么会有区别呢?如果可以的话,我想只使用较短的令牌对象,因为它更小并且在作为 API 公开时更容易管理。新的 CompositeToken 由 Swagger 编码,并在每个引号前添加 / 字符,如下所示:
[{/"compositeToken/":{/"token":/"+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMzhVMTE7NTc7NDUvNjc2NDozNFsA#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=/",/"range/":{/"min/":/"/",/"max/":/"FF/"}},/"orderByItems/":[{/"item/":/"2019-09-27T00:46:34.5653923Z/"}],/"rid/":/"xS0oAMD5rWYLAAAAAAAAAA==/",/"skipCount/":0,/"filter/":null}]
这意味着我必须正确解码字符串才能使用它,这似乎是 API 消费者的额外负担。我错过了什么吗?关于此 CompositeToken 对新 SDK 的作用以及我们为何进行此更改的文档似乎并不多。
编辑
我发现如果我将 .Replace("\"", "'") 添加到新 SDK 中返回的 ContinuationToken 我现在有一个版本表示我的 API 消费者可以使用它来传递下一页,因为单引号不会自动编码。但是我不确定这是处理它的最干净的方法,并希望获得一些意见。非GitHub 项目中的样本中的一部分进入了这个。我还想知道复合令牌中使用了哪些附加属性,例如 "range" 和 "orderByItems",因为它没有明确记录。
编辑 2
事实证明,当我使用 Swagger UI 时,用单引号替换双引号有效,但当我使用 Postman 时却无效。很奇怪。当我使用 Postman 时,与在 Swagger 中工作的完全相同的调用(使用 compositeToken 的单引号版本)给出了以下错误:
Response status code does not indicate success: 400 Substatus: 0
Reason: (Invalid JSON in continuation token
[{'compositeToken':{'token':' RID:xS0oAMD5rWYLAAAAAAAAAA== for
OrderBy~Context, exception: Unterminated string. Expected delimiter:
'. Path '[0].compositeToken.token', line 1, position 58.).
编辑 3
这是原始 continuationToken 在由 SwaggerUI 和 Postman 返回时的样子。如您所见,该字符串中有双引号,因此消费者在字符串中添加了额外的反斜杠以转义双引号以获得结果。显然,按原样将其传回会导致无效的 JSON 错误,这需要用户或服务必须对其进行更正。
是否有管理此问题的最佳实践?还考虑提取 "token" 属性 并将其传回给用户(因为这是以前的 SDK 使用的),然后在传回时将其注入 CompositeToken 字符串,因为它出现好像 CompositeToken 的其余属性永远不会改变(也许这是以前的 SDK 所做的?) - 但我担心如果这种格式发生变化,这在未来可能会中断。
编辑 4
作为参考,这是之前 SDK 中的 continuationToken 的样子:
编辑 5
我想通了为什么将双引号替换为单引号的标记在 Postman 中不起作用。似乎有一个已知的错误,Postman 在字符串参数的第一个哈希符号之后删除任何字符:https://github.com/postmanlabs/postman-app-support/issues/6023 因为令牌中有多个“#”,所以当通过 Postman 作为请求参数。进入体内后效果很好。
这是我的发现。根据您的查询复杂性,您的令牌(或复合令牌)可能具有其他属性或完全不同的结构。例如,在您使用 ORDERBY 的调用中,您的令牌将如下所示:
[{'compositeToken':{'token':'+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMzhVMTE7NTc7NDUvNjc2NDozNFsA#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=','range':{'min':'','max':'FF'}},'orderByItems':[{'item':'2019-09-27T00:46:34.5653923Z'}],'rid':'xS0oAMD5rWYLAAAAAAAAAA==','skipCount':0,'filter':null}]
如您所见,这包括 "orderByItems"、"skipCount" 的 属性 和过滤器。另请注意,它包含在 "compositeToken" 对象中。
在我只执行 CONTAINS 查询(或根本没有 WHERE 子句)的其他调用中,令牌看起来更简单并且没有包装在 "compositeToken" 对象中根本。它也不包括上面的许多属性。
[{'token':'+RID:xS0oAMD5rWYNAAAAAAAAAA==#RT:1#TRC:1#ISV:2#IEO:65551#FPC:AQ0AAAAAAAAADQAAAAAAAAA=','range':{'min':'','max':'FF'}}]
两者唯一 属性 的共同点是 "token" 和 "range"似乎是最低限度。
所以是的,您确实必须保持令牌的完整性,因为它以字符串格式按原样提供给您。
我通过在将字符串返回给用户之前对字符串执行 .Replace("\"", "'") 解决了转义字符的问题。对于 Postman,您必须将字符串传回正文,因为使用 queryString 会在“#”符号处截断(这是 Postman 的一个已知问题,如我的原始 post 中所述)。
希望这对像我一样对 Microsoft.Azure.Cosmos SDK 中的新延续令牌格式以及如何在客户端应用程序(包括 OpenAPI/SwaggerUI 和 Postman)中使用它们感到好奇的人有所帮助。
我正在从 Microsoft.Azure.DocumentDB.Core SDK 迁移到新的 Microsoft.Azure.Cosmos SDK(版本 3.2)。
较旧的 SDK returns ResponseContinuation 中的 ContinuationToken 属性 看起来像这样:
+RID:knNRALdSjOBBAQAAAAAAAA==#RT:1#TRC:10#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMjlVMjg7MTQ7MTkvMTE6ODgyOFsA#ISV:2#IEO:65536#FPC:AgEAAAAKAAyBIwBA3L8PAAQ=
新的 SDK returns 它在 ContinuationToken 属性 中作为一个 JSON 字符串表示一个 "CompositeToken" 对象并且看起来像这样:
[{"compositeToken":{"token":"+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMzhVMTE7NTc7NDUvNjc2NDozNFsA#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=","range":{"min":"","max":"FF"}},"orderByItems":[{"item":"2019-09-27T00:46:34.5653923Z"}],"rid":"xS0oAMD5rWYLAAAAAAAAAA==","skipCount":0,"filter":null}]
当我只取出令牌时:
+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMzhVMTE7NTc7NDUvNjc2NDozNFsA#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=
我收到以下错误:
Invalid JSON in continuation token +RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:z9path31ttPskBzzyJFdBTQ0NDQ0AA==#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA= for OrderBy~Context, exception: Unexpected character encountered while parsing value: +. Path '', line 0, position 0.
但是如果我传入整个复合令牌,它就可以工作。我有点困惑,因为这两个 SDK 都只是使用 CosmosDB 服务的 warppers 那么为什么会有区别呢?如果可以的话,我想只使用较短的令牌对象,因为它更小并且在作为 API 公开时更容易管理。新的 CompositeToken 由 Swagger 编码,并在每个引号前添加 / 字符,如下所示:
[{/"compositeToken/":{/"token":/"+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMzhVMTE7NTc7NDUvNjc2NDozNFsA#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=/",/"range/":{/"min/":/"/",/"max/":/"FF/"}},/"orderByItems/":[{/"item/":/"2019-09-27T00:46:34.5653923Z/"}],/"rid/":/"xS0oAMD5rWYLAAAAAAAAAA==/",/"skipCount/":0,/"filter/":null}]
这意味着我必须正确解码字符串才能使用它,这似乎是 API 消费者的额外负担。我错过了什么吗?关于此 CompositeToken 对新 SDK 的作用以及我们为何进行此更改的文档似乎并不多。
编辑
我发现如果我将 .Replace("\"", "'") 添加到新 SDK 中返回的 ContinuationToken 我现在有一个版本表示我的 API 消费者可以使用它来传递下一页,因为单引号不会自动编码。但是我不确定这是处理它的最干净的方法,并希望获得一些意见。非GitHub 项目中的样本中的一部分进入了这个。我还想知道复合令牌中使用了哪些附加属性,例如 "range" 和 "orderByItems",因为它没有明确记录。
编辑 2
事实证明,当我使用 Swagger UI 时,用单引号替换双引号有效,但当我使用 Postman 时却无效。很奇怪。当我使用 Postman 时,与在 Swagger 中工作的完全相同的调用(使用 compositeToken 的单引号版本)给出了以下错误:
Response status code does not indicate success: 400 Substatus: 0 Reason: (Invalid JSON in continuation token [{'compositeToken':{'token':' RID:xS0oAMD5rWYLAAAAAAAAAA== for OrderBy~Context, exception: Unterminated string. Expected delimiter: '. Path '[0].compositeToken.token', line 1, position 58.).
编辑 3
这是原始 continuationToken 在由 SwaggerUI 和 Postman 返回时的样子。如您所见,该字符串中有双引号,因此消费者在字符串中添加了额外的反斜杠以转义双引号以获得结果。显然,按原样将其传回会导致无效的 JSON 错误,这需要用户或服务必须对其进行更正。
是否有管理此问题的最佳实践?还考虑提取 "token" 属性 并将其传回给用户(因为这是以前的 SDK 使用的),然后在传回时将其注入 CompositeToken 字符串,因为它出现好像 CompositeToken 的其余属性永远不会改变(也许这是以前的 SDK 所做的?) - 但我担心如果这种格式发生变化,这在未来可能会中断。
编辑 4
作为参考,这是之前 SDK 中的 continuationToken 的样子:
编辑 5
我想通了为什么将双引号替换为单引号的标记在 Postman 中不起作用。似乎有一个已知的错误,Postman 在字符串参数的第一个哈希符号之后删除任何字符:https://github.com/postmanlabs/postman-app-support/issues/6023 因为令牌中有多个“#”,所以当通过 Postman 作为请求参数。进入体内后效果很好。
这是我的发现。根据您的查询复杂性,您的令牌(或复合令牌)可能具有其他属性或完全不同的结构。例如,在您使用 ORDERBY 的调用中,您的令牌将如下所示:
[{'compositeToken':{'token':'+RID:xS0oAMD5rWYLAAAAAAAAAA==#RT:1#TRC:2#RTD:fUTWI3DNPK3FpLhdCXlVBTMxMjouMTouMzhVMTE7NTc7NDUvNjc2NDozNFsA#ISV:2#IEO:65551#FPC:AQkAAAAAAAAADQAAAAAAAAA=','range':{'min':'','max':'FF'}},'orderByItems':[{'item':'2019-09-27T00:46:34.5653923Z'}],'rid':'xS0oAMD5rWYLAAAAAAAAAA==','skipCount':0,'filter':null}]
如您所见,这包括 "orderByItems"、"skipCount" 的 属性 和过滤器。另请注意,它包含在 "compositeToken" 对象中。
在我只执行 CONTAINS 查询(或根本没有 WHERE 子句)的其他调用中,令牌看起来更简单并且没有包装在 "compositeToken" 对象中根本。它也不包括上面的许多属性。
[{'token':'+RID:xS0oAMD5rWYNAAAAAAAAAA==#RT:1#TRC:1#ISV:2#IEO:65551#FPC:AQ0AAAAAAAAADQAAAAAAAAA=','range':{'min':'','max':'FF'}}]
两者唯一 属性 的共同点是 "token" 和 "range"似乎是最低限度。
所以是的,您确实必须保持令牌的完整性,因为它以字符串格式按原样提供给您。
我通过在将字符串返回给用户之前对字符串执行 .Replace("\"", "'") 解决了转义字符的问题。对于 Postman,您必须将字符串传回正文,因为使用 queryString 会在“#”符号处截断(这是 Postman 的一个已知问题,如我的原始 post 中所述)。
希望这对像我一样对 Microsoft.Azure.Cosmos SDK 中的新延续令牌格式以及如何在客户端应用程序(包括 OpenAPI/SwaggerUI 和 Postman)中使用它们感到好奇的人有所帮助。