通过查询模式通过子对象访问父对象的受保护字段
Access to protected field of parent object through child object via a query schema
我正在使用 graphql-spqr,这样我就不必创建 schema.graphql
个文件。
我有一个基础 class,我的大多数其他 class 都继承自该基础。例如
@GraphQLInterface(name = "BaseResponse", implementationAutoDiscovery = true)
@ToString
@Data
public class BaseResponse {
@JsonInclude(Include.NON_NULL)
protected String responseCode;
@JsonInclude(Include.NON_NULL)
protected String responseDescription;
protected String hash;
}
其他class继承自上述基础class如下
@ToString(callSuper = true)
@Data
@AllArgsConstructor
public class GetAllGroupResponse extends BaseResponse {
private List<Group> groups;
}
当我像下面这样设置 GetAllGroupResponse
的父值时
getAllGroupResponse.setResponseCode(ResponseCodeEnum.SH_97.getRespCode());
getAllGroupResponse.setResponseDescription(ResponseCodeEnum.SH_97.getRespDescription());
我希望从我的 graphql 查询请求中检索 responseCode 的值
{
getAllPagable(pageNumber : 1, numberOfRecords : 3) { responseCode groups { groupName } }
}
但它在下面抛出一个错误,告诉我它看不到 responseCode 变量,因为它不是 class GetAllGroupResponse
的直接 属性
Validation error of type FieldUndefined: Field 'responseCode' in type 'GetAllGroupResponse' is undefined @ 'getAllPagable/responseCode'
PS。 BaseResponse
来自导入到当前项目的另一个 package/library 项目
UPDATE
基于 GitHub 提出的问题和提供的解决方案。我创建了一个 bean,如下所示
@Bean
public ExtensionProvider<GeneratorConfiguration, ResolverBuilder> resolverBuilderExtensionProvider() {
String[] packages = {"com.sheeft.microservices.library", "com.sheeft.mircoservice.groups"};
return (config, current) -> {
List<ResolverBuilder> resolverBuilders = new ArrayList<>();
//add a custom subtype of PublicResolverBuilder that only exposes a method if it's called "greeting"
resolverBuilders.add(new PublicResolverBuilder() {
@Override
public PublicResolverBuilder withBasePackages(String... basePackages) {
return super.withBasePackages(packages); //To change body of generated methods, choose Tools | Templates.
}
});
//add the default builder
resolverBuilders.add(new AnnotatedResolverBuilder().withBasePackages(packages));
return resolverBuilders;
};
}
现在我收到一条错误消息
object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'responseCode' is missing
于是决定手动添加getResponseCode
getter方法,运行成功。当我调用 /graphql
端点时,它抛出异常
Object required to be not null",
"trace": "graphql.AssertException: Object required to be not null
我想你只需要为你的项目设置基础包。例如
generator.withBasePackages("your.root.package", "library.root.package")
或者,如果您使用的是 SPQR Spring Starter,请添加
graphql.spqr.base-packages=your.root.package,library.root.package
添加到您的 application.properties
文件,效果相同。
当你有一个 类 的层次结构跨多个包(甚至库,就像你的情况)让 SPQR 知道应该公开哪些包时,这是需要的,否则它可能会意外公开一些框架代码甚至核心 Java 诸如 getClass.
之类的东西
我正在使用 graphql-spqr,这样我就不必创建 schema.graphql
个文件。
我有一个基础 class,我的大多数其他 class 都继承自该基础。例如
@GraphQLInterface(name = "BaseResponse", implementationAutoDiscovery = true)
@ToString
@Data
public class BaseResponse {
@JsonInclude(Include.NON_NULL)
protected String responseCode;
@JsonInclude(Include.NON_NULL)
protected String responseDescription;
protected String hash;
}
其他class继承自上述基础class如下
@ToString(callSuper = true)
@Data
@AllArgsConstructor
public class GetAllGroupResponse extends BaseResponse {
private List<Group> groups;
}
当我像下面这样设置 GetAllGroupResponse
的父值时
getAllGroupResponse.setResponseCode(ResponseCodeEnum.SH_97.getRespCode());
getAllGroupResponse.setResponseDescription(ResponseCodeEnum.SH_97.getRespDescription());
我希望从我的 graphql 查询请求中检索 responseCode 的值
{
getAllPagable(pageNumber : 1, numberOfRecords : 3) { responseCode groups { groupName } }
}
但它在下面抛出一个错误,告诉我它看不到 responseCode 变量,因为它不是 class GetAllGroupResponse
Validation error of type FieldUndefined: Field 'responseCode' in type 'GetAllGroupResponse' is undefined @ 'getAllPagable/responseCode'
PS。 BaseResponse
来自导入到当前项目的另一个 package/library 项目
UPDATE
基于 GitHub 提出的问题和提供的解决方案。我创建了一个 bean,如下所示
@Bean
public ExtensionProvider<GeneratorConfiguration, ResolverBuilder> resolverBuilderExtensionProvider() {
String[] packages = {"com.sheeft.microservices.library", "com.sheeft.mircoservice.groups"};
return (config, current) -> {
List<ResolverBuilder> resolverBuilders = new ArrayList<>();
//add a custom subtype of PublicResolverBuilder that only exposes a method if it's called "greeting"
resolverBuilders.add(new PublicResolverBuilder() {
@Override
public PublicResolverBuilder withBasePackages(String... basePackages) {
return super.withBasePackages(packages); //To change body of generated methods, choose Tools | Templates.
}
});
//add the default builder
resolverBuilders.add(new AnnotatedResolverBuilder().withBasePackages(packages));
return resolverBuilders;
};
}
现在我收到一条错误消息
object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'responseCode' is missing
于是决定手动添加getResponseCode
getter方法,运行成功。当我调用 /graphql
端点时,它抛出异常
Object required to be not null", "trace": "graphql.AssertException: Object required to be not null
我想你只需要为你的项目设置基础包。例如
generator.withBasePackages("your.root.package", "library.root.package")
或者,如果您使用的是 SPQR Spring Starter,请添加
graphql.spqr.base-packages=your.root.package,library.root.package
添加到您的 application.properties
文件,效果相同。
当你有一个 类 的层次结构跨多个包(甚至库,就像你的情况)让 SPQR 知道应该公开哪些包时,这是需要的,否则它可能会意外公开一些框架代码甚至核心 Java 诸如 getClass.
之类的东西