Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use custom directives alongside graphql.java.extended.validation #74

Open
paulbuechner opened this issue Sep 9, 2022 · 1 comment

Comments

@paulbuechner
Copy link

paulbuechner commented Sep 9, 2022

Describe the bug
When wiring the default graphql.java.extended.validation setup with the RuntimeWiringConfigurer provided by the new Spring for GraphQL project, custom directives that are registered via the builders directive() method don't seem to apply anymore.

To Reproduce

  1. Implement the official graphql-java DateFormattingDirective:
directive @DateFormat on FIELD_DEFINITION

type Person {
    id: ID!
    name: String!
    createdAt: String! @DateFormat
}
public class DateFormattingDirective implements SchemaDirectiveWiring {

    private static final String FORMAT = "format";

    @Override
    public GraphQLFieldDefinition onField(
        SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition> env) {

        GraphQLFieldDefinition fieldDefinition = env.getElement();
        GraphQLFieldsContainer fieldsContainer = env.getFieldsContainer();

        // DataFetcherFactories.wrapDataFetcher is a helper to wrap data fetchers so that
        // CompletionStage is handled correctly along with POJOs
        DataFetcher<?> originalFetcher = env.getCodeRegistry()
            .getDataFetcher(fieldsContainer, fieldDefinition);
        DataFetcher<?> dataFetcher = DataFetcherFactories.wrapDataFetcher(originalFetcher,
            ((dataFetchingEnvironment, value) -> {

                if (value instanceof LocalDateTime localDateTime
                    && dataFetchingEnvironment.containsArgument(FORMAT)) {

                    String dateTimePattern = dataFetchingEnvironment.getArgument(FORMAT);
                    DateTimeFormatter dateTimeFormatter = buildFormatter(dateTimePattern);
                        return dateTimeFormatter.format(localDateTime);
                    }
                }

                return value;
            }));

        // This will extend the field by adding a new "format" argument to it for the date
        // formatting which allows clients to opt into.
        FieldCoordinates coordinates = FieldCoordinates.coordinates(fieldsContainer,
            fieldDefinition);
        env.getCodeRegistry().dataFetcher(coordinates, dataFetcher);

        return fieldDefinition.transform(builder -> builder.argument(
            GraphQLArgument.newArgument().name(FORMAT).type(Scalars.GraphQLString)));
    }

    private static DateTimeFormatter buildFormatter(String format) {
        return DateTimeFormatter.ofPattern(format);
    }
}
  1. Wire the custom DateFormattingDirective alongside the standard setup of the graphql.java.extended.validation project:
@Configuration
public class GraphQLConfig {
  
    @Bean
    public RuntimeWiringConfigurer validationConfigurer() {
        ValidationRules validationRules = ValidationRules.newValidationRules()
            .onValidationErrorStrategy(OnValidationErrorStrategy.RETURN_NULL)
            .build();

        ValidationSchemaWiring schemaWiring = new ValidationSchemaWiring(validationRules);

        return builder -> builder.directiveWiring(schemaWiring).build();
    }

    @Bean
    public RuntimeWiringConfigurer directiveConfigurer() {
        return builder -> builder
            .directive("DateFormat", new DateFormattingDirective())
            .build();
    }
}
  1. See the functionality of the custom DateFormattingDirective disappear.

Without graphql.java.extended.validation:
grafik

With graphql.java.extended.validation:
grafik

Note, Registering both graphql.java.extended.validation SchemaWiring and CustomDirective inside a single Bean wont help either.

@yeikel
Copy link

yeikel commented Jun 17, 2024

We are also seeing this with a custom directive

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants