Access to protected field of parent object through child object via a query schema

冷暖自知 提交于 2019-12-11 17:05:13

问题


I am using graphql-spqr So that I don't have to create schema.graphql files.

I have a base class in which most of my other classes inherit from. For example

@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;

}

Other classes inherit from the above base class as below

@ToString(callSuper = true)
@Data
@AllArgsConstructor
public class GetAllGroupResponse extends BaseResponse {

    private List<Group> groups;
}

When I set the parent values of GetAllGroupResponse like below

 getAllGroupResponse.setResponseCode(ResponseCodeEnum.SH_97.getRespCode());  
 getAllGroupResponse.setResponseDescription(ResponseCodeEnum.SH_97.getRespDescription());

I wish to retrieve the value of responseCode from my graphql query request

{ getAllPagable(pageNumber : 1, numberOfRecords : 3) { responseCode groups { groupName } } }

but it throws an error below which tells me it can't see the responseCode variable because it is not a direct property of the class GetAllGroupResponse

Validation error of type FieldUndefined: Field 'responseCode' in type 'GetAllGroupResponse' is undefined @ 'getAllPagable/responseCode'

PS. BaseResponse is from a different package/library project that was imported into the current project

UPDATE

Based on the GitHub issues raised and solutions provided. I created a bean as below

@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;
        };
    }

and now I get an error which says the following

object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'responseCode' is missing

So I decided to add the getResponseCode getter method manually and it runs successfully. When I the call the /graphql endpoint it throws an exception

Object required to be not null", "trace": "graphql.AssertException: Object required to be not null


回答1:


I think all you need is to set the base packages for your project. E.g.

generator.withBasePackages("your.root.package", "library.root.package")

Or, if you're using SPQR Spring Starter, add

graphql.spqr.base-packages=your.root.package,library.root.package

to your application.properties file, for the same effect.

This is needed when you have a hierarchy of classes across multiple packages (or even libraries, like in your case) to let SPQR know which packages should be exposed, because otherwise it might accidentally expose some framework code or even core Java things like getClass.



来源:https://stackoverflow.com/questions/56802809/access-to-protected-field-of-parent-object-through-child-object-via-a-query-sche

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!