带有 Java/Spring Boot 的 GraphQL 无法从传递的查询中选择定义为在模式中的字段上定义的自定义指令

Posted

技术标签:

【中文标题】带有 Java/Spring Boot 的 GraphQL 无法从传递的查询中选择定义为在模式中的字段上定义的自定义指令【英文标题】:GraphQL with Java/Springboot unable to pick custom directive defined as onField in schema from passed query 【发布时间】:2021-08-11 20:42:52 【问题描述】:

已在 schema 中的 directives.graphql 文件中定义了自定义指令:

directive @reference on FIELD

还在我的 GraphQLConfig.java 类中传递了 .graphql 文件:

private static final String[] SCHEMA_FILES = new String[]"schema/root.graphql","schema/directives.graphql","schema/train-details.graphql";

root.graphql 如下:

schema query: Query
type Query trainDetails( trainId: String!): TrainDetail

train-details.graphql 如下:

type TrainDetail trainId: String trainStatus: String

在传递给springboot graphql API的请求中,我想检查指令@reference是否被传递,然后在代码中执行一些业务逻辑。在 Java 中服务器启动期间生成的架构中存在指令,但是当我从请求中传递的查询中提取指令时,它不存在。

查询传入请求,url(本地启动服务器)

http://localhost:8080/graphql

GraphQL 查询:

query($trainId: String!)trainDetails(trainId: $trainId)trainStatus @reference

查询变量:

 "trainId": "123456"

dataFecther(graphql config 类中也添加了),其中检查传递请求中的指令:

public DataFetcher getTrainDetailsDataFecther() return environment -> trainDetailsFetcher.getTrainDetails.getTrainDetails(environment);

getTrainDetails 方法:

public TrainDetails getTrainDetails(DataFectchingEnvironment environment) if(environment.getQueryDirectives().getImmediateDirective("reference").isEmpty())//perform some logic    

if 检查总是返回 false,即使在请求查询中将 @reference 作为指令传递也是如此。它无法识别查询中已在 FIELD 上传递了指令。

请注意,该指令是在 FIELD 而不是 FIELD DEFINITION,因此未在 train-details.graphql 中添加指令作为架构中的定义。

【问题讨论】:

【参考方案1】:

我通过 Twitter 联系了 Tejas Shikhare (https://twitter.com/tejas26),他很友好地回复了我代码的问题:

    getQueryDirectives.getImmediateDirective 在字段 trainDetails 而不是 trainStatus 上运行。 Datafetcher 在特定字段上实现。 一种在选择字段中访问查询指令的方法,但您可以为 selectionField 的 trainStatus 实现您自己的属性数据提取器,并从 DataFetchingEnvironment 访问该指令。 更多关于属性数据提取的信息:https://www.graphql-java.com/documentation/v11/schema/

有两种方法可以解决此问题:

    将请求中传递的查询更改为下面,这是如果您想捕获 TrainDetails 上的指令:

    查询($trainId: String!)trainDetails(trainId: $trainId)@referencetrainStatus

    在GraphQLConfig类中为trainStatus添加dataFetcher,详见链接:https://www.graphql-java.com/documentation/v11/schema/ 这是如果你想在 TrainStatus 上捕获指令

这两种解决方案我都试过了,效果很好!

【讨论】:

以上是关于带有 Java/Spring Boot 的 GraphQL 无法从传递的查询中选择定义为在模式中的字段上定义的自定义指令的主要内容,如果未能解决你的问题,请参考以下文章

Java Spring Boot 加 Spring Batch 创建 Jar 并仅运行特定作业

Java Spring Boot 测试:如何从测试上下文中排除 java 配置类

Java Spring boot hibernate删除级联数据

无法在 Java Spring Boot / Angular 应用程序中获取 cookie

Spring Boot 返回 405 而不是 404 用于 POST 到未知 URL

java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Boot Starter的介绍及使用