使用Hot Chocolate和.NET 6構建GraphQL應用(7) —— 實現Query分頁功能

系列導航

使用Hot Chocolate和.NET 6構建GraphQL應用文章索引

需求

GraphQL中的查詢分頁相對來說是查詢中比較難理解的,接口的Schema也和其他不一樣。在這篇文章中,我們來實現簡單的查詢分頁。

思路

Hot Chocolate提供了兩種排序方式:基於Cursor的分頁和基於Offset的分頁。這兩種方式的區別在於:基於Cursor的分頁是隨結果返回每條數據的一個游標字符串,下次分頁查詢是通過Where子句來比較游標的大小來決定去獲取哪一部分的數據;而基於Offset的方式,是類似於傳統的後端分頁方式,即使用OFFSET(SKIP+TAKE)方式去獲取數據,後者在面對數據庫會發生頻繁變動(插入或刪除數據)或者面對大量數據集的時候性能不如前者。但是對於基於Cursor的分頁方式而言,如果對一個沒有建立索引的數據列使用WhereOrder By,速度是不如Order ByOFFSET的。

在這篇文章中,我們會實現這兩種不同方式的分頁效果。Hot Chocolate分別提供了UsePagingUseOffsetPaging屬性來完成分頁需求。

實現

要使用分頁屬性,需要在接口上方添加UsePagingUseOffsetPaging即可,注意屬性添加的順序。

  • Query.cs
[UsePaging]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<Post> GetPosts([Service] IRepository<Post> repository) => repository.GetAsQueryable();

或者

[UseOffsetPaging]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<Post> GetPosts([Service] IRepository<Post> repository) => repository.GetAsQueryable();

這樣就實現了查詢結果的分頁,同時我們可以在注入Hot Chocolate的地方進行全局配置:

builder.Services
    .AddGraphQLServer()
    .SetPagingOptions(new PagingOptions
    {
        MaxPageSize = 50,
        IncludeTotalCount = true
    })
    .AddFiltering()
    .AddProjections()
    .AddSorting()
    .AddQueryType<Query>()
    .AddType<PostType>();

下面我們來驗證一下。

驗證

啟動Api項目,調用接口:

img

可以看到在返回體中數據已經按照我們指定的排序和分頁結果返回了,注意在返回中包含了totalCount(這是我們在全局配置中指定一起返回的),在pageInfo中指出了是否有下一頁或上一頁,使用Cursor進行分頁的關鍵之處在於返回體中還包含了每條記錄的cursor值。接下來我們指定下次獲取數據的起始游標值:

img

這樣就獲取了後一頁的數據。

接下來我們看一下使用Offset方式分頁的結果:

img

在這種方式下,我們看到了熟悉的skiptake參數,如果需要獲取下一頁數據,只需要修改skip參數即可:

img

總結

在本文中我們實現了查詢的分頁,關於分頁更詳細的說明請參考官方文檔:Pagination。那麼GraphQL的查詢部分就說完了,下一篇文章將會介紹如何進行數據的修改。