如何使用Sangria的@GraphQLField注解创建嵌套GraphQL字段
实现Sangria嵌套解析器的方案
当然可以实现这种嵌套字段的解析需求!这正是GraphQL分阶段解析、按需获取数据的核心优势之一,用Sangria完全能做到。
核心思路
你需要为Item定义一个带有@GraphQLField标注的解析类型,让item字段返回这个类型,然后每个嵌套字段(status、price)各自实现从对应数据源获取数据的逻辑。
具体实现步骤
1. 定义Item的类型和解析逻辑
首先创建Item的基础结构,再为它定义带有GraphQL字段的解析逻辑(如果需要从不同数据源获取数据,用trait封装方法会更灵活):
// 定义Item的基础结构,可根据实际业务调整 case class Item(id: String) // 为Item封装不同字段的解析逻辑 trait ItemResolvers { // 从数据源B获取status @GraphQLField def status(ctx: Context[MyContext, Item]): Future[String] = { // 这里编写从数据源B获取该Item状态的逻辑 ctx.ctx.queries.getStatusFromDataSourceB(ctx.value.id) } // 从数据源C获取price @GraphQLField def price(ctx: Context[MyContext, Item]): Future[Double] = { // 这里编写从数据源C获取该Item价格的逻辑 ctx.ctx.queries.getPriceFromDataSourceC(ctx.value.id) } }
2. 修改MyQuery中的item方法
让原来的item方法返回Item类型(异步场景下返回Future[Item]):
trait MyQuery { @GraphQLField def item(ctx: Context[MyContext, Unit])(id: String): Future[Item] = { // 这里先获取Item的基础信息,比如从主数据源加载或直接构造实例 Future.successful(Item(id)) } }
3. 更新Schema定义
为Item生成对应的ObjectType,并确保它被纳入Schema中:
// 生成Item的ObjectType,关联之前定义的解析逻辑 val ItemType: ObjectType[MyContext, Item] = deriveObjectType[MyContext, Item]( AddFields(ItemResolvers.status, ItemResolvers.price) ) // 更新Schema定义,确保Item类型被正确识别 val schema = Schema( deriveContextObjectType[MyContext, MyQuery, Unit](_.queries), additionalTypes = List(ItemType) )
工作原理
当你执行目标GraphQL查询时:
query { item(id: "123") { status price } }
Sangria会先解析item字段得到Item实例,再分别调用status和price对应的解析方法——这两个方法可以独立访问不同的数据源,完全满足你的需求。
内容的提问来源于stack exchange,提问作者tgk
相关产品推荐
相关产品推荐

