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

1

0

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

Metameric answered 28/6, 2019 at 7:39 Comment(0)
B
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.

Bobo answered 29/6, 2019 at 8:31 Comment(3)
@alexdavies You're doing a lot of needless weird stuff, you don't need any of that. Just try what I told you. And you didn't mention you were using SPQR Spring Starter, that's important info.Bobo
I did as asked and I get the following error object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'hash' is missing object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'responseCode' is missing object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'responseDescription' is missingMetameric
I deeply apologize. I was using an older version of your library version 0.03 I switched to version 0.05 and it works now.Metameric

© 2022 - 2024 — McMap. All rights reserved.