How I validate user input in golang
Tags: go
Published: 2019-11-22 22:11:59

Every application needs some way to validate the user inputs, this prevents the wrong kind of inputs been entered before ever reaching the database.

Coming from a Node.Js background for API service development, I always do some validation on the backend with JOI, I wanted something great to work with also in golang.

Using golang has a lot of advantages and I found been strongly typed one of the many useful features of golang.

The strongly typed built-in feature of golang already provided some sort of validation for the application, let's dive into some code.


Let's say you want to build an application, with the model defined below:


![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/9w3hpnyor3izwzwpw417.png)

With the code above, the type of each field has been defined with some tags

In the route handler function, we will decode the request into the struct defined above.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/fvvpl6fwjgvm4zfo239r.png)

Let us try to send a request but with a different type for the phoneNumber field (type int).


![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/1j5lrhm0v5d60te9nl5q.png)

The response gotten is below:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/c2z9w0mn0mpvutzbi571.png)

This shows that there is some form of validation already in Go because it is strongly typed.

But there is so much we can do with this, some listed below:

1. What if the right type was entered or it was ignored totally and not sent? 

2. What if I want to set a minimum amount of entry to be entered for maybe a password or a phone number not to exceed a particular length?

So I needed to find a way to validate each field and not re-invent the wheel.

I came across a validation package (https://godoc.org/gopkg.in/go-playground/validator.v9) amongst many out there and it is quite easy to use.

You add to the tags already defined as shown below:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/lfz8olf0v9v2efww69ng.png)

That way, we have some constraints defined already for each field required been the minimum. 

We need to do just a little bit more.

1. Import the validation package into our application.

2. Define a way for the errors to be returned.

3. Use it in our route handler function.

4. Test it!

Let's do that.

1. 


![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/xumu4xut2jqa990892vl.png)

2.
I created a helper function that takes a type interface (actually just any type of struct) and returns a bool (true) and errors (a map of key string and value string holding the field that failed validation and the corresponding error fail) or it returns false and nil if it passed the validation as shown below:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/nflbhoj3g0oau6f62u7m.png)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/tnk399kk1dfjehmbcjv5.png)


PS: All just one code. You can find a very good explanation of the code above in the link below.

(https://stackedco.de/validating-rest-input-fields-using-golang-structs)

3.
Let's make use of our validator helper in our handler.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ifz0e0yy4x2cbyumixfn.png)

4.
Let's go for a ride with our code.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/1hhz3akygitqeh26qpvs.png)

Notice we left out the phoneNumber field, the validator returned the field and the error.


![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/tseevssrv4yfg76lc9aa.png)

Now we have a working validation process for our application.

Let's deal with another case.

I struggled with really, Imagine you have to embed another struct in your model struct and this can be required for many reasons one of them been you are performing a left join in your database query and need to return this new struct fields alongside the initial query, but you want to avoid validating this field since it is not required for the user to input the fields.

There is also a way to avoid this, all you have to do is in the embedded struct, add a validate with "-" as shown below:

 ![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/to9n6fj7euhyxfs34hv5.png)

This way, it is ignored when validating even if validations are required on the struct definition.

Thanks for reading!!

PS: This is my first post.