GraphQL按需获取请求字段及参数传递问题(DGS框架)
问题1:在GraphQL中通过其他查询实现字段的按需获取
你想要的按需加载子字段效果完全可以实现,但不能直接在Schema里写cars: getCars()这种语法(GraphQL Schema不支持直接引用查询函数)。借助DGS框架的@DgsData注解,可以实现完全等价的懒加载效果。
实现步骤:
- Schema定义(保持原有结构):
type Query { getVehicles: Vehicles getCars: [Car!] getBuses: [Bus!] getTrucks: [Truck!] } type Vehicles { cars: [Car!] buses: [Bus!] trucks: [Truck!] } type Car { plate: String } type Bus { plate: String } type Truck { plate: String }
- Java代码实现:
getVehicles仅返回空的Vehicles对象,不预加载任何子字段数据- 为
Vehicles的每个子字段单独编写数据获取逻辑,通过@DgsData指定父类型和对应字段名
@DgsComponent public class VehicleDataFetcher { @DgsQuery public Vehicles getVehicles() { // 返回空对象,子字段将按需加载 return new Vehicles(); } // 复用原getCars逻辑作为Vehicles.cars的数据源 @DgsData(parentType = "Vehicles", field = "cars") public List<Car> getVehiclesCars() { System.out.println("Fetching cars..."); return List.of(new Car("CAR123"), new Car("CAR456")); } @DgsData(parentType = "Vehicles", field = "buses") public List<Bus> getVehiclesBuses() { System.out.println("Fetching buses..."); return List.of(new Bus("BUS123"), new Bus("BUS456")); } @DgsData(parentType = "Vehicles", field = "trucks") public List<Truck> getVehiclesTrucks() { System.out.println("Fetching trucks..."); return List.of(new Truck("TRUCK123"), new Truck("TRUCK456")); } // 保留原有独立查询(如需保留) @DgsQuery public List<Car> getCars() { return getVehiclesCars(); } }
效果说明:
- 当客户端请求
getVehicles { cars }时,仅触发getVehiclesCars()执行,不会加载buses和trucks数据 - 当请求
getVehicles { buses trucks }时,仅触发对应两个数据获取方法,完全实现按需加载
问题2:将父查询的输入字段传递给子查询
要把getVehicles的state参数传递给子字段cars/buses/trucks,可以通过DgsDataFetchingEnvironment从上下文提取,或直接从父对象获取参数。
实现方案1:通过上下文传递参数
- Schema定义:
type Query { getVehicles(state: String!): Vehicles } type Vehicles { cars: [Car!] buses: [Bus!] trucks: [Truck!] } type Car { plate: String }
- Java代码实现:
@DgsComponent public class VehicleDataFetcher { @DgsQuery public Vehicles getVehicles(@InputArgument String state, DgsDataFetchingEnvironment dfe) { // 将state存入上下文,供子字段获取 dfe.getGraphQlContext().put("state", state); return new Vehicles(); } @DgsData(parentType = "Vehicles", field = "cars") public List<Car> getCars(DgsDataFetchingEnvironment dfe) { // 从上下文提取父级传递的state String state = dfe.getGraphQlContext().get("state"); System.out.println("Fetching cars for state: " + state); return List.of(new Car(state + "-CAR123"), new Car(state + "-CAR456")); } // buses和trucks的实现逻辑类似 @DgsData(parentType = "Vehicles", field = "buses") public List<Bus> getBuses(DgsDataFetchingEnvironment dfe) { String state = dfe.getGraphQlContext().get("state"); System.out.println("Fetching buses for state: " + state); return List.of(new Bus(state + "-BUS123"), new Bus(state + "-BUS456")); } }
实现方案2:通过父对象传递参数
如果Vehicles类包含state属性,可直接从父对象提取参数:
// 修改getVehicles方法,将state存入Vehicles对象 @DgsQuery public Vehicles getVehicles(@InputArgument String state) { Vehicles vehicles = new Vehicles(); vehicles.setState(state); return vehicles; } // 子字段从父对象获取state @DgsData(parentType = "Vehicles", field = "cars") public List<Car> getCars(DgsDataFetchingEnvironment dfe) { Vehicles parentVehicles = dfe.getSource(); String state = parentVehicles.getState(); // 后续数据查询逻辑 return List.of(new Car(state + "-CAR123"), new Car(state + "-CAR456")); }
效果说明:
当客户端请求getVehicles(state: "CA") { cars }时,getCars方法可获取到CA参数,执行对应的数据查询。
内容的提问来源于stack exchange,提问作者Abbin Varghese
相关产品推荐
相关产品推荐

