Go

More on validating with Go

A few days ago I posted about a new Go package called validator that we initially developed for our own internal use at project7.io but what fun is internal stuff, right? So we opensourced it.

Then Matthew Holt pointed me to an ongoing discussion
on validation happening on martini-contrib’s github. By the way, if you don’t know martini yet, go rectify that right now.

And today I learned about check, which takes a completely different
approach to data validation than the one we took, which by the way is totally fine and you should check it out.

Good to know we were not the only ones with the problem. Although I’m happy with how our package turned out, I kind of wish
I had found these other guys earlier. Could have shared some code or just ideas.

[ANN] Package validator

The thing about working in a startup under stealth mode is you can’t often talk about what you’re doing. Thankfully, from time to time, an opportunity appears that lets us at least share something tangential.

A large part of our project at project7.io involves receiving data from a client (generally in JSON) for processing. This involves unmarshaling the JSON into a struct, something that Go does very well. But then comes the boring part: checking that the information sent from the client is correct and complete before doing anything with it.

The boring life of validating stuff

1
<span class='line'><span class="k">if</span> <span class="nx">t</span><span class="p">.</span><span class="nx">Username</span> <span class="o">!=</span> <span class="s">""</span> <span class="o">&&</span> <span class="nx">t</span><span class="p">.</span><span class="nx">Age</span> <span class="p">></span> <span class="mi">18</span> <span class="o">&&</span> <span class="nx">t</span><span class="p">.</span><span class="nx">Foo</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="o">&&</span> <span class="nb">len</span><span class="p">(</span><span class="nx">t</span><span class="p">.</span><span class="nx">Bar</span><span class="p">.</span><span class="nx">Baz</span><span class="p">)</span> <span class="p">></span> <span class="mi">8</span> <span class="o">&&</span> <span class="o">...</span>
</span>

We had to do this often and for a large number of different structs and sometimes a struct gained a new field and we had to go back and see that it was being properly validated everywhere. It was so boring that we ended up writing something to make it easier for us. We’ve been using this for a while and now we decided to open source it in the hopes that it might be useful for others.

Package validator implements validation of variables. Initially we had implemented JSONschema but we don’t always deal with JSON, we also get data as XML and sometimes as form-encoded. So we changed our approach and went right to the struct definitions.

A struct definition with some validation rules attached

1
2
3
4
5
6
7
8
<span class='line'><span class="kd">type</span> <span class="nx">T</span> <span class="kd">struct</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">A</span> <span class="kt">int</span>    <span class="s">`validate:"nonzero"`</span>
</span><span class='line'>  <span class="nx">B</span> <span class="kt">string</span> <span class="s">`validate:"nonzero,max=10"`</span>
</span><span class='line'>  <span class="nx">C</span> <span class="kd">struct</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">Ca</span> <span class="kt">int</span>    <span class="s">`validate:"min=5,max=10"`</span>
</span><span class='line'>      <span class="nx">Cb</span> <span class="kt">string</span> <span class="s">`validate:"min=8, regexp:^[a-zA-Z]+"`</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span>

This allowed us to attach validation rules right to the data structure definitions. Then instead of large, boring list of if statements, we were able to validate in single function call.

Validating an instance of a struct

1
2
3
<span class='line'><span class="k">if</span> <span class="nx">valid</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">validator</span><span class="p">.</span><span class="nx">Validate</span><span class="p">(</span><span class="nx">t</span><span class="p">);</span> <span class="p">!</span><span class="nx">valid</span> <span class="p">{</span>
</span><span class='line'>  <span class="c1">// not valid, so return an http.StatusBadRequest of something</span>
</span><span class='line'><span class="p">}</span>
</span>

Multiple rules for different situations

We often use the same struct to deal with different data coming from the client. Sometimes we only care about one or two of the fields in one scenario, so we also supported multiple rules like, say

A struct with two different sets of rules

1
2
3
4
<span class='line'><span class="kd">type</span> <span class="nx">T</span> <span class="kd">struct</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">A</span> <span class="kt">int</span>    <span class="s">`foo:"nonzero" bar:"min=5,max=10"`</span>
</span><span class='line'>  <span class="nx">B</span> <span class="kt">string</span> <span class="s">`bar:"nonzero"`</span>
</span><span class='line'><span class="p">}</span>
</span>

In scenario foo, we need A to be non-zero, but we don’t care for what is in B. In the bar scenario, however, we need B to be non-zero and the value of A to be between 5 and 10, inclusive. To validate, we then make validator use a different tag name for each case

WithTag() FTW

1
2
3
<span class='line'><span class="nx">t</span> <span class="o">:=</span> <span class="nx">T</span><span class="p">{</span><span class="nx">A</span><span class="p">:</span> <span class="mi">3</span><span class="p">}</span>
</span><span class='line'><span class="nx">validator</span><span class="p">.</span><span class="nx">WithTag</span><span class="p">(</span><span class="s">"foo"</span><span class="p">).</span><span class="nx">Validate</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span> <span class="c1">// valid</span>
</span><span class='line'><span class="nx">validator</span><span class="p">.</span><span class="nx">WithTag</span><span class="p">(</span><span class="s">"bar"</span><span class="p">).</span><span class="nx">Validate</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span> <span class="c1">// invalid</span>
</span>

We can also change the tag by using SetTag with will then make the tag name persistent until changed again by another call to SetTag.

Please refer to http://godoc.org/gopkg.in/validator.v1 for a lot more documentation, use cases, and how to access the individual validation errors found for each field.

Anagramizer, a simple anagram solver in Go

This weekend I took the family to celebrate Father’s Day away from town. We went around getting to know parts of the province we live in and never been to.

We came back yesterday and the plan today was for a nice, calm day at home (it’s a holiday of some sort here.) Then I got engaged in a game called Hanging with Friends, a mix of the traditional hangman with a bit of Scrabble.

Since English isn’t my first language, I have a limited vocabulary, which leaves me at a disadvantage against my English-speaking friends. I can handle the “hangman” part of the game where I have to guess the word my friends come up with; but when it becomes “Scrabble” and I’ve got to form words using only a given set of letters and still make them difficult enough that a native English speaker will have problems figuring them out, then it’s tough.

An itch that needed some scratching. Enter Anagramizer.

When I woke up this morning, I decided to write a little program to help me. You call it cheating, I call it having a bit of nerd fun.

Being that I’m currently in love with Go, I decided to write in that language and it was really easy and quick to do it. It took me about half an hour to write the program that did what I needed. But then…

I succumbed to the temptation and started adding bells and whistles. Admittedly it was mostly for my own amusement and trying stuff in Go, but by the time we were leaving for lunch, the program had more options than the KDE audio volume utility (see what I did just there?)

I decided to make it available to anyone who wants to play with it. It served its purpose of entertaining me for about half a day 🙂

It’s now available on Github and released under a BSD licence.

Euler 9 in Go

This was surprising to me. For fun I picked one of the Euler algorithms I played with in the past and rewrote it in Go. The idea was to rewrite it idiomatically to see how different things might look. Nothing else. The very first thing I did was to get the exact algorithm and rewrite, no idiomatic changes.

[go]
package main

import “fmt”

func isTriplet(a, b, c int) bool {
return a * a + b * b == c * c
}

func main() {
for a := 1; a < 1000; a++ {
for b := a + 1; b < (1000 – a) / 2; b++ {
c := 1000 – a – b
if isTriplet(a, b, c) {
fmt.Println(a * b * c)
return
}
}
}

}
[/go]

What surprised me is that this thing runs in 0.005s, which is faster than the Python implementation and very close to the one in C. It surprised me because this wasn’t really supposed to happen. The Go compiler isn’t well optimized, especially compared to compilers with a many-years headstart.