在哪里存储以及如何在客户端维护来自 cosmos db 的 continuation Token
Where to store and how to maintain the continuation Token from cosmos db at client side
我计划使用 cosmos db 延续令牌实现分页。我的 api 将 return 结果和继续令牌发送给客户。我的问题是哪个是存储延续令牌的最佳位置?令牌也会根据每个后续请求而改变吗?如何维护之前的continousTokens?
此处显示我们从何处获取值,而不是将其存储在何处How to pass\user azure continue token via webAPI
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?
例如:如果有 100 条记录并且 pageSize=10 并且 pageNumbers 是 1,2,3,4,5,6,7,8,9,10 并且如果用户随机点击任何页面。在那种情况下如何获取所需的记录?或者如果我在下面的屏幕截图中放置“上一个”按钮并想在列表中返回。
https://i.stack.imgur.com/BMwI2.gif
是的,每个请求的令牌都会发生变化,因此您可以使用以前的令牌检索以前的页面。
如果将令牌传递给客户端以保持后端无状态,则不应在 URL 或 URL 查询中发送令牌,因为令牌可能会变得非常大。在客户端中,您可以将令牌保存在内存中。在大多数情况下,没有必要保留令牌,因为令牌应该是短暂的。它应该是短暂的,因为分页结果反映了每个页面请求之间发生的所有更改。
根据评论更新
由于令牌可能很大,因此必须在请求正文中传递,这也意味着它不应该是 GET 请求。
另一种解决方案是在后端(具有一些有限的 TTL)将令牌存储在具有较小密钥(例如 GUID)的缓存中,并仅在后端和客户端之间传递密钥。这样您就可以在 URL 或 URL 查询中传递密钥。但这需要后端保持状态。
我计划使用 cosmos db 延续令牌实现分页。我的 api 将 return 结果和继续令牌发送给客户。我的问题是哪个是存储延续令牌的最佳位置?令牌也会根据每个后续请求而改变吗?如何维护之前的continousTokens?
此处显示我们从何处获取值,而不是将其存储在何处How to pass\user azure continue token via webAPI
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?
例如:如果有 100 条记录并且 pageSize=10 并且 pageNumbers 是 1,2,3,4,5,6,7,8,9,10 并且如果用户随机点击任何页面。在那种情况下如何获取所需的记录?或者如果我在下面的屏幕截图中放置“上一个”按钮并想在列表中返回。
https://i.stack.imgur.com/BMwI2.gif
是的,每个请求的令牌都会发生变化,因此您可以使用以前的令牌检索以前的页面。
如果将令牌传递给客户端以保持后端无状态,则不应在 URL 或 URL 查询中发送令牌,因为令牌可能会变得非常大。在客户端中,您可以将令牌保存在内存中。在大多数情况下,没有必要保留令牌,因为令牌应该是短暂的。它应该是短暂的,因为分页结果反映了每个页面请求之间发生的所有更改。
根据评论更新
由于令牌可能很大,因此必须在请求正文中传递,这也意味着它不应该是 GET 请求。
另一种解决方案是在后端(具有一些有限的 TTL)将令牌存储在具有较小密钥(例如 GUID)的缓存中,并仅在后端和客户端之间传递密钥。这样您就可以在 URL 或 URL 查询中传递密钥。但这需要后端保持状态。