Spring for GraphQL request validation using directives.

This tutorial is about one powerful tool that GraphQL has. This tool validates query input. And it's called a directive. I will show you how to use the existing library and implement a custom one.

Ivan Polovyi
Javarevisited
4 min readJul 4, 2022

--

The tutorial is based on the Java Spring Boot application. This application has one controller with one API, that accepts 3 arguments each argument has its requirements. The first argument cannot be empty, the second has to contain numbers only because then this argument will be converted to an integer. And the third has to be a date with a defined format because it will be converted to a LocalDate. API will receive input, combine it into the string, and return it to a user—a really simple example, but it is enough to understand how a directive works. The complete code you can find here:

If you are interested in GraphQL for Spring you can check my other blogs:

The Controller class :

Extended Validation for graphql-java

To be able to validate the input parameters the easiest way is to use an already existing API called Extended Validation for graphql-java. Complete source code and documentation you can find here. We just have to add a dependency to the POM file.

After we need to create a Spring config class like the below:

This config class creates validation rules, and validation schema wiring, and then registers it as directive wiring to the RuntimeWiringConfigurer Bean.

Now we can use all directives from this API in the query definition file of the project. I will show the example with only 2 directives, you can find more on the API documentation page.

The query definition file:

First, we have to declare a directive, and then add this directive to the argument, after the type of the argument. The declaration consists of the word “directive” the name of the directive, the directive arguments, and their default values. For example, @NotBlank has only one argument — the message and @Pattern has two of them, the message and regexp. At last, every directive has a specification on what type it can be used.

The default arguments of a directive can be overridden if needed. In the example above the @Pattern overrides one argument. The message of course can be overridden too.

Custom validation error

Usually, in my day-to-day programming life, I customize the error messages. To do this we have to create the Exception class that implements GraphQLError.

More about GraphQL exception handling and error customization you can find below:

The next step is to create a class that implements the MessageInterpolator interface. This class has to be annotated with @Component annotation so that Spring can create a bean.

The object from this class intercepts the error and customizes the error message by adding the argument name to the message. And customizes the error response by returning the object from the previously created class.

The last step is to add this object to the validation rules in the config class:

And the schema definition file now looks like the below:

As you can see now we have our custom message as a default one for the @NotBlank directive. When the validation error will be thrown, this massage will be customized in the message interpolator.

Custom directive

Sometimes the list of directives in the API won't fulfill your needs. So you have to create your own. In this example, we will add a directive for date format validation. To do that we have to create a class that extends an AbstractDirectiveConstraint class.

This class specifies the name of the directive as DateTimeFormatter. It has a method runConstraint that receives a method argument named format and basically does all the job to validate the string date against specified in the directive format. After the class is created we have to add it to the config class.

Now we can use this directive in our query definition file:

The project has a Postman collection that can be used to test the entire project.

Short demo video:

Conclusion

In this tutorial, I’ve explained how to use directives and create custom ones. As programmers, we have a library with ready-to-use directives that can be used with minimal adjustment to the code. In special cases we can create our own directive with minimum effort, that will fulfill our requirements. Thank you for reading! Please like and follow. If you have any questions or suggestions, please feel free to write me on my LinkedIn account.

--

--

Ivan Polovyi
Javarevisited

I am a Java Developer | OCA Java EE 8 | Spring Professional | AWS CDA | CKA | DCA | Oracle DB CA. I started programming at age 34 and still learning.