HotChocolate同一查询类型如何同时支持分页与全量结果返回
HotChocolate 单查询字段同时支持分页/全量返回实现方案
结论:HotChocolate 原生支持该需求,无需维护两套独立查询字段,通过动态挂载中间件即可实现单字段兼容两种查询模式,核心实现逻辑如下:
具体实现步骤
1. 调整查询方法定义
首先移除查询方法上固定写死的分页、过滤、排序特性,新增一个布尔类型的控制参数paginate,默认值设为true,保证原有分页调用的兼容性:
[UseDbContext(typeof(MyContext))] public IQueryable<User> Users( ClaimsPrincipal claims, [Service] MyContext context, bool paginate = true) { // 底层数据查询逻辑完全复用,不需要重复编写 return context.Users; }
2. 动态配置字段中间件
通过HotChocolate提供的字段描述器配置能力,根据paginate参数的值动态决定是否挂载分页、过滤、排序中间件:
public class QueryTypeConfig : ObjectType<Query> { protected override void Configure(IObjectTypeDescriptor<Query> descriptor) { descriptor.Field(x => x.Users(default!, default!, default)) .UseWhen( // 判断条件:本次请求传入paginate=true时才挂载分页相关中间件 fieldContext => fieldContext.ArgumentValue<bool>("paginate"), // 需要动态挂载的中间件配置 paginatedFieldBuilder => paginatedFieldBuilder .UseOffsetPaging() .UseFiltering() .UseSorting() ); } }
UseWhen是HotChocolate内置的条件中间件扩展,不会破坏原有字段的参数结构,也不会引入额外的性能开销。
3. 调用方式说明
配置完成后,同一个users字段自动支持两种调用模式:
- 分页查询:和原有调用逻辑完全一致,客户端不需要做任何修改,默认
paginate=true,支持传入skip/take分页参数、过滤条件、排序规则,返回标准的分页结构(包含items/pageInfo/totalCount字段) - 全量查询:请求时传入参数
paginate: false即可,此时字段不会返回分页包装结构,直接返回User类型的全量数组,分页、过滤、排序参数会被自动忽略。
实践建议
- 全量查询场景建议增加数据量上限校验,比如单次最多返回1000条数据,避免一次性拉取超大结果集压垮数据库
- 如果使用游标分页而非偏移分页,只需要把配置里的
UseOffsetPaging()替换为UsePaging()即可,逻辑完全一致 - 该方案完全复用底层查询逻辑,没有重复代码,所有原有业务逻辑(比如权限校验、数据过滤)只需要写一次。
内容的提问来源于stack exchange,提问作者Rafael Cronemberger
相关产品推荐
相关产品推荐

