Resolver 模型
字段解析函数、Resolver 链、与 Controller 对照。
30 分钟
Resolver 模型
Resolver 是字段级解析函数:给定父对象、参数、上下文,返回该字段的值。GraphQL 引擎按 Query 树 自顶向下 调用 Resolver 链。
学习目标
- 理解「每个字段一个 Resolver」的默认模型
- 区分根 Resolver 与嵌套字段 Resolver
- 与 Spring
@RestController方法对照
核心内容
解析流程
Query.track(slug)
→ Track 对象
→ Track.lessons → List<Lesson>
→ Lesson.title → String
REST 里一个 getTrack(slug) 可能 JOIN 拉全量;GraphQL 里 lessons Resolver 仅在被请求时 执行。
Java 伪代码
@Component
public class TrackResolver {
public Track track(DataFetchingEnvironment env) {
String slug = env.getArgument("slug");
return trackService.findBySlug(slug);
}
public List<Lesson> lessons(Track track) {
return lessonService.findByTrackSlug(track.getSlug());
}
}
等价 REST 见 spring-boot-essentials TrackController:@GetMapping("/{slug}") 一次返回 DTO。Resolver 把 编排拆到字段级——灵活,也带来 N+1 风险(gql-nplus1)。
Context 与鉴权
// context 注入当前用户、DataLoader 等
GraphQLContext context = env.getGraphQlContext();
Long userId = context.get("userId");
类似 Spring Security 在 Filter 链放入 SecurityContext;Mutation 写操作必须在 Resolver 内校验权限,不能假设 Schema 隐藏字段等于安全。
与 MongoDB / JPA
- JPA:
trackService走 MySQLcf_track(本站主库) - 实验:某字段 Resolver 可读 MongoDB 评论集合(mongodb-essentials)
GraphQL 不绑定存储;Resolver 是 集成层。
练习
- 画出
track { lessons { title } }的 Resolver 调用顺序 - 说明:若
lessons未被 Query 选中,lessonsResolver 是否执行 - 对比
TrackController.list()与 Resolver 的职责边界