Data, Maps, Usability, and Performance

Simple App with Go, Martini, Gorp and MySQL

Last updated on February 9, 2014 in Development

app in go lang

Last week I saw a video on the Martini web framework for Go and it inspired me to check it out. Looking at the performance of Go is even more inspiring and today I decided to learn the Go language and write a really simple app with Go, Martini, and MySQL. I started using the native SQL package for Go but quickly adopted gorp as it looks like a really clean API to talk to the database. I have also leveraged the binding and render Martini utilities to abstract more of the code out of my main go file. The app will create a table in mysql, create some sample posts, show a homepage with these posts, show an individual post view, and allow the end user to create their own post. I will also dig into error handling, validation, converting timestamps, and properly using layout template in the render utility for good SEO.

Sample Martini App

At first, I took a look at a Martini blog example on GitHub which does a good job of showing how Martini can work with MySQL and how to leverage the render utility to quickly use HTML templates. But, it’s a really simple example, and it does not show how to create a blog post with an SQL INSERT command and you need to setup the database and tables before running the code. Here are some good resources on working with SQL and Go Lang:

Go Database SQL
Go SQL Interface
Go MySQL Examples
SQL Go Examples

After browsing these SQL examples, I quickly figured out how to make an INSERT statement in GO:

As you can see above, you use the Prepare and Exec calls. It would be nice if we could abstract this code out of the main file so I started looking for some database ORM libraries and found Gorp. It really simplifies the SQL code, lets you make tables from structs, and has a clean chainable API. The quickstart example goes through most of what we need so I leveraged that for mySQL instead of sqlite.

Since I am now using the Go struct for the SQL table fields I will need to convert some fields. For example, I’m happy storing created time of a post as Unix timestamp and int64 but I want to display it as a nice looking date. The Martini render utility uses Go’s html/template package to render html templates and this is a good place to perform this kind of conversions. Here are some great Go resources for working with HTML templates:

Go Template Examples
Templates in GO
GO Templates

So, inside the template files I am using a {{.Created}} variable to display the created time of the post and this is where I manage the way time is displayed. The test file for the render utility has a nice example of using helper function maps for templates to access. Here is how I use a template.FuncMap to convert a unix timestamp into a nice date for a template file that that calls the function with {{.Created | formatTime}}:

Now, the body is stored in the database as a string and displayed in the template as a string but I want the HTML tags to be properly parsed. The martini blog had a Description field with type template.HTML which enabled string to HTML conversion but GORP does not seem to support template.HTML types right now. So, I decided to also write a FuncMap conversion function for that as well. Here are the two Martini render options:

And inside the template files I use {{.Body | unescaped}}. I am using a layout.tmpl file to structure the HTML markup and its great that I can use a variable in the layout.tmpl file in addition to {{yiled}} because you want unique metadata information in website HEAD tag for SEO. I wrote a map in the Martini function that includes a custom title and the struct and I pass that to render function. Here is how the layout.tmpl looks like and how I loop through the array of posts in the posts.tmpl template file:

The form in posts.tmpl is used to create a post into the database, which is routed by using the Post method in Martini:

Notice how binding is used for Title and Body form field validation. You can either put something on the struct or create a custom function for it. Finally, an individual post with some custom error validation and error template generation:

Check out how it all works here. Forms currently only allow GET and POST so next time I will show how to use Ajax and JSON to update a post with a PUT call, delete a post with a DELETE method, and I will wrap it up with users and sessions, login, registration, and authentication, as well as querying posts by users.

External:
create structs from sql DB in GO
GO Databases and GORP
Martini app with MongoDB
Build web apps with GO Lang ebook
Contributed Martini Handlers and Utilities
Writing a golang app with mysql
Context aware HTML templates in GoLang
Micro framework with Go
10 things you didnt know about Go Lang
Go Language Tutorial: Methods on Structs
Go Lang Reflection
GoKu, A GOlang web mvc framework
GoLang Parse Templates Example
GoLang Base Template Example
Convert int64 to String in Go
Simple FuncMap example in GO
Timestamps in MySQL and GO

Tags: , ,

Facebook Twitter Hacker News Reddit More...