在哪里存储以及如何在客户端维护来自 cosmos db 的延续令牌

Posted

技术标签:

【中文标题】在哪里存储以及如何在客户端维护来自 cosmos db 的延续令牌【英文标题】:Where to store and how to maintain the continuation Token from cosmos db at client side 【发布时间】:2020-12-01 12:26:40 【问题描述】:

我计划使用 cosmos db 延续令牌实现分页。我的 api 将返回结果和继续令牌给客户端。我的问题是哪个是存储延续令牌的最佳位置?此外,每个后续请求都会更改令牌?如何维护之前的 continousTokens?

这里显示了我们从哪里获取值,而不是在哪里存储它How to pass\user azure continue token via webAPI Pagination in Cosmos DB using Page Size and Page Number

controller.cs

        [Route("myApps")]
        [HttpGet]
        public async Task<IActionResult> GetAllAppsAsync(string continuationToken, CancellationToken cancellationToken)
        
            var user = this.GetUser();
            var results = await this.appRepository.GetAppsForUserAsync(user, continuationToken, cancellationToken).ConfigureAwait(false);
            var result = this.mapper.Map<AppHeader[]>(results.Value);
            return this.Ok(new KeyValuePair<string, AppDefinitionHeader[]>(results.Key, result));
        
Repository.cs

 public async Task<KeyValuePair<string, IEnumerable<App>>> GetAppForUserAsync(User user,  string continuationToken, CancellationToken cancellationToken)
        
            
            try
            
                FeedOptions queryOptions = new FeedOptions
                
                    MaxItemCount = 2,
                    RequestContinuation = continuationToken
                ;
                string token = string.Empty;
                var query = this.factory.GetClient()
                    .CreateDocumentQuery<AppDefinitionResource>(
                        UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName),
                        queryOptions)
                    .AsDocumentQuery();

                List<AppDefinition> results = new List<AppDefinition>();
                while (query.HasMoreResults && results.Count <= 2)
                
                    cancellationToken.ThrowIfCancellationRequested();

                    var response = await query.ExecuteNextAsync<App>(cancellationToken).ConfigureAwait(false);

                    var apps = this.mapper.Map<App[]>(response);
                    results.AddRange(apps);
                    token = response.ResponseContinuation;
                

                return new KeyValuePair<string, IEnumerable<App>>(token, results);
            
           
        

更新:

如何维护之前的continousTokens?

Ex : 如果有 100 条记录并且 pageSize=10 并且 pageNumbers 是 1,2,3,4,5,6,7,8,9,10 并且如果用户在任何页面上随机点击。在那种情况下如何获取所需的记录?或者只是如果我在下面的屏幕截图中放置“上一个”按钮并想要在列表中遍历。

https://i.stack.imgur.com/BMwI2.gif

【问题讨论】:

这取决于您 - 您需要将其返回给 API 的客户端,并公开一种方法,让您的客户端将分页传递回您的 API。 嘿,马丁,刚刚更新了问题,正在将 continuationToken 和结果传递给客户端,以及在后续请求中如何绑定从客户端传递的控制器中的 continuationToken?我不能使用 [FromUri] 因为令牌非常大,而且由于 Get 请求我也不能使用 body。这里的最佳做法是什么? 【参考方案1】:

是的,每个请求的令牌都会更改,因此您可以使用以前的令牌检索以前的页面。

如果您将令牌传递给客户端以保持后端无状态,则不应在 URL 或 URL 查询中发送令牌,因为令牌可能会变得非常大。在客户端中,您可以将令牌保存在内存中。在大多数情况下,没有必要保留令牌,因为令牌应该是短暂的。它应该是短暂的,因为分页结果反映了每个页面请求之间发生的所有更改。


基于 cmets 更新

由于令牌可能很大,它必须在请求正文中传递,这也意味着它不应该是 GET 请求。

另一种解决方案是将令牌存储在具有较小密钥(例如 GUID)在后端(具有一些有限的 TTL)的缓存中,并在后端和客户端之间传递密钥。这样您就可以在 URL 或 URL 查询中传递密钥。但这需要后端保持状态。

【讨论】:

嘿莫,刚刚更新了问题,正在将 continuationToken 和结果传递给客户端,以及在后续请求中如何绑定从客户端传递的控制器中的 continuationToken?我不能使用 [FromUri] 因为令牌非常大,而且我也不能因为 Get 请求而使用 body。这里的最佳做法是什么? @DeepakKothari 我扩展了答案。这能回答你的问题吗? 我使用“POST”请求实现了这个,这里我的疑问是如何维护以前的 continuosTokens?如何维护之前的 continousTokens?例如:如果有 100 条记录并且 pageSize=10 并且 pageNumbers 是 1,2,3,4,5,6,7,8,9,10 并且如果用户在任何页面上随机点击。在那种情况下如何获取所需的记录?或者只是如果我在下面的屏幕截图中放置“上一个”按钮并想要在列表中遍历。 i.stack.imgur.com/BMwI2.gif 不确定您的确切意思,但无论如何这应该在单独的问题中提出。 嘿@Mo,我想向后翻页。我想我需要这样做***.com/questions/52357925/… 或者如果您有任何想法,请告诉我。

以上是关于在哪里存储以及如何在客户端维护来自 cosmos db 的延续令牌的主要内容,如果未能解决你的问题,请参考以下文章