Spring for GraphQL request validation

Every app has to have some mechanism to validate the user input. The input validation serves 2 purposes. First, it will guarantee an app's smooth operation even if the user makes the request with invalid parameters. Second, it can explain to the user what the user does wrong and give a hint through the message on how to resolve the error. This blog is about user input validation in a web app based on Spring for GraphQL.

Ivan Polovyi
Javarevisited
5 min readJun 27, 2022

--

Spring for GraphQL is a new way of creating GraphQL applications. At the time of writing it’s been released as a stable version. It is very easy to use and the setup and configuration are made using annotations. I like it a lot.

The hardest part for me was understanding how to validate the user input. When I develop an application I want to have control over input validation errors. Because I want to customize the error message to make it more specific and intuitive. The default messages are good but they tend to be more general to serve all possible cases. And one more important tink for me is to be able to present an error to users in their native language, using users' location.

Most of the time I create a REST web application using Spring Boot. Validation errors in a REST Spring Boot application can be customized by creating a class annotated with @RestControllerAdvice, and creating a separate method for every exception annotated with @ExceptionHandler. The Spring for GraphQL has a similar approach. More you can find below. This blog explains exception handling in REST and GraphQL.

This tutorial is based on a simple application that has one endpoint. When querying this endpoint the user has to provide the name and the birth date. The query has some requirements.

Both parameters are required and the date has to be in the format of yyyy-MM-dd. And the birth date has to be before today. After the query pass all these validations the endpoint will return a simple string informing a name and age of a user. Very simple app, nothing complicated, I just wanted to focus on the main purpose — input validation. The query definition :

The complete code for this application can be found below:

The application has configuration classes and files with the messages that allow it to create error messages in 2 different languages (English and Ukrainian), based on the Accept-Language header received on the request. I won’t explain it in detail to don’t lose the focus of the tutorial. But I think by poking around in the configuration package of the project you can figure it out.

To make sure the user will provide the required fields the method arguments are annotated with @NotNull annotation.

If a user provides the birth date that is after the today date then the application will throw an exception.

As I've said before to handle exceptions in the Spring for GraphQL we have to create a special class that implement the interface DataFetcherExceptionResolver and implements its method. And this class handles exceptions and can override the exception messages using customer one and using the appropriate language.

Until now everything is working fine. But what about cases when the user passes an invalid query? The query which can't be parsed, for example, the query with a missing curly brace. Or when the user provides a query with an unknown argument.

Or when the user passes the date with the wrong format for example MM-dd-yyyy instead of the required one yyyy-MM-dd. It turns out this kind of validation error can not be handled inside the exception handler class.

The GraphQL just does not propagate this type of error to that point. The full explanation of this issue can be found here. And Java GraphQL does not have any mechanism for this either, as mentioned here, although it is working on it.

With no native option left, I've created one “workaround”. The Spring for GraphQL has the concept of a response interceptor. Where one can create a class that implements the WebGraphQlInterceptor interface and override its method. Then inside this method, the response can be intercepted and errors can be extracted and overridden.

When the user inputs an invalid query then the error has a type of Invalid syntax. This error can be easily overridden and a custom message can be inserted. Things get complicated when the user puts an unknown argument or invalid format for the argument.

In both situations, the type of error is a validation error. And to inform the user we have to get the name of the parameter. The response object just doesn’t have this information as separate parameters.

All needed information about the type of the error and the field that causes the error is presented in the message error, as a string. So the only way to extract necessary information is to parse the error message.

First, we get the type of the error by extracting it from the message and converting it to an enum, and then based on this enum the program decides on what type of error it is. And second, we get the name of the parameter.

The project has a Postman collection that you can use to perform tests. Short demo video you can check below:

Conclusion

In this tutorial, I've explained how to overcome a temporary limitation of a Spring for GraphQL validation errors customization. This is not the perfect solution, but at the moment, in my opinion, is the one that can fix the problem. Thank you for reading! 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.