1
votes

Have defined a custom directives in the directives.graphql file in the schema:

directive @reference on FIELD

Have also passed the .graphql file in my GraphQLConfig.java class:

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

root.graphql is as below:

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

train-details.graphql is as below:

type TrainDetail{ trainId: String trainStatus: String}

In the passed request to the springboot graphql API, I want to check if the directive @reference is passed then perform some business logic in the code. The schema which is generated during server start up in Java has the directive present in it but when I extract the directive from the passed query in the request it is not present.

query passed in request, url (starting server locally)

http://localhost:8080/graphql

GraphQL query:

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

Query Variables:

{ "trainId": "123456"}

dataFecther(which has been added in graphql config class as well) in which checking the directives in the passed request:

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

getTrainDetails method:

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

The if check is always returning false, even when @reference is passed in the request query as a directive. It is not recognizing that a directive has been passed on FIELD in the query.

Please note that this is directive is On FIELD and not on FIELD DEFINITION, hence not added the directive in train-details.graphql as a definition in the schema.

1

1 Answers

0
votes

I reached out to Tejas Shikhare (https://twitter.com/tejas26) over Twitter and he was kind enough to respond to me with what the issue with the code is:

  1. getQueryDirectives.getImmediateDirective is operating on the field trainDetails instead of the trainStatus.
  2. Datafetcher is implemented on a specific field.
  3. A way to access the query directives in a selection field but what you can do is implement your own property data fetcher for the selectionField trainStatus and access the the directive there from the DataFetchingEnvironment.
  4. More about property datafetcheres here : https://www.graphql-java.com/documentation/v11/schema/

There are two ways to resolve the issue:

  1. Change the query passed in the request to below, this is if you want to capture the directive on TrainDetails:

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

  2. Add the dataFetcher for trainStatus in the GraphQLConfig class, as detailed in the link: https://www.graphql-java.com/documentation/v11/schema/ This is if you want to capture the directive on TrainStatus

I have tried both the solutions and it worked!