Gqlgen Custom Data Validation — Part 1
In this article, we will create our custom data validation for the gqlgen library.
Before you start reading this, I assume that you know about creating a simple app with gqlgen.
Why Gqlgen?
Gqlgen is a powerful library to generate a graphql API architecture.
- Schema First, which will help us generate code from Graphql Schema that we write before
- Type Safety; we will rarely see map[string]interface{}; most of the responses will use a model
- Codegen, most of the repeating part will be generated so that we only focus on the important part of the code
Libraries
Get Started
Repo: https://github.com/david-yappeter/gqlgen-validation-example
Initialize a go mod and go get libraries needed
# Initialize
go mod init myapp
go get github.com/99designs/gqlgen
go get github.com/go-playground/validator# gqlgen init
go run github.com/99designs/gqlgen init
The project directory should look like this for now:
explanation:
- gqlgen.yml: config file for gqlgen generator
- graph/*.graphqls: Pre-written GraphQL schema (user-defined)
- graph/*.resolvers.go: output of generated GraphQL schema
- graph/model/models_gen.go: All model will be generated inside this file
- graph/generated/generated.go: repeating action that generated by gqlgen
Define and Generating Our Schema
graph/schema.graphqls
graph/user.graphqls
I will use variable to store the user instead of database to make the explanation shorter and more focused on data validation.
@goField is build-in directives by gqlgen that allow us to force generate a resolver.
We will add a go generate for our gqlgen in graph/resolvers.go
package graph//go:generate go run github.com/99designs/gqlgen// This file will not be regenerated automatically.//// It serves as dependency injection for your app, add any dependencies you require here.type Resolver struct{}
To generate the Schema, type this command:
go generate ./...
Erase the code from ‘!!! Warning!’ to the end of the file.
Create User Service
service/user.go :
graph/schema.resolvers.go :
graph/user.resolvers.go :
After creating the user service (create and get all), we assign the function to the correct resolver.
Testing Our Code
Until this point, we will test our code without a validation yet.
go run server.go# output:
# connect to http://localhost:8080/ for GraphQL playground
Try to access http://localhost:8080 and we will see our graphql Playground.
First we will try to Get All Users :
Then it’s confirmed that our code is still working well.
Next we will try to create our first and second user.
Then we will Get All Users again :
Custom Validation with Directives
Gqlgen supports Custom Directives which allow us to create our data validation for an input.
How to add the custom directives?
We will add the custom directives @binding in graph/schema.graphqls.
...
directive @goField(forceResolver: String, name: String) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION
directive @binding(constraint: String!) on INPUT_FIELD_DEFINITION | ARGUMENT_DEFINITION
...
And apply the directive to our NewUser model.
input NewUser {
name: String! @binding(constraint: "required,max=20")
email: String! @binding(constraint: "required,email")
age: Int! @binding(constraint: "gte=0,lte=128")
country_id: String! @binding(constraint: "required,iso3166_1_alpha2")
}
Then go generate ./… the code and binding directive will be created.
The only thing we still need to do is create the function for binding and apply it to the directive.
directives/binding.go :
By using github.com/go-playground/validator, the parameter passed by the gqlgen system will be validated through the directives using the validator, available tags can be found on the library itself.
We edit server.go to apply the func to the directives:
We have completed the validation part, now it’s time for a testing:
But as we can saw from the examples, the error message is not helpful enough. We can fix this thing by adding one more library ‘github.com/go-playground/universal-translator’ that makes the error message more ‘meaningful’.
directives/binding.go :
server.go :
This will solve the error message problem, and we can edit the default translation tag to our custom message.
Try to run again the code, and we will see a different error message now :
That’s all for the Part-1 of gqlgen data validation, Part-2 will discuss about gqlgen Plugin and how to create plugin with a data validation build-in.
Hope this article help you :)