Its been long since working with go language, been awesome experience so far. This post is regarding how one can structure go application in MVC structure like Rails. This example would be using Martini - A Golang MVC and Gorm - A Golang MVC, for demonstration purpose only.
So, to start we would have application directory structure contaning
1.) config: config folder will contain all config files as needed and/or migrations
2.) models: models will contain all models referencing to their counterpart in database tables
3.) controllers: as usual this will contain all controllers
4.) templates: all templates will go to this directory, though this cane be named as views.
5.) server.go: this file will contain main function and routing, though routing can also be moved to seperate file.
Now what we would be developing, is a activity model named models/activity.go
packaged as models
, here is snippet of same
//models/activity.go
package models
import(
"time"
"github.com/jinzhu/gorm"
_ "github.com/go-sql-driver/mysql"
)
type Activity struct {
ID uint `gorm:"primary_key" form:"id"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
Title string `form:"title" binding:"required"`
Description string `form:"description"`
City string `form:"city" binding:"required"`
Address string `form:"address"`
Contact string `form:"contact"`
}
but wait, we could move fields common for all models into seperate generic model, here is how it looks after
//models/model.go
package models
import(
"time"
"github.com/jinzhu/gorm"
_ "github.com/go-sql-driver/mysql"
)
type Model struct {
ID uint `gorm:"primary_key" form:"id"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
and our beloved activity.go
Now Activity
can be referred as models.Activity
wherever needed (but of-course we need to import it)
Next we would first look into our server.go
file contaning main function for our app, Here is how it looks
So what we are doing here is to import relevent packages as needed. Map gorm.DB
to martini context and declare routing. Do not worry about what controllers.IndexActivities
would be doing. We would come to that next.
Next, we need to define out activities controller as controllers/activities
under controllers package. Here is how our activities controller looks like
package controllers
import(
"net/http"
"fmt"
"log"
"github.com/go-martini/martini"
"github.com/codegangsta/martini-contrib/render"
"github.com/jinzhu/gorm"
_ "github.com/go-sql-driver/mysql"
"../models"
)
func IndexActivities(render render.Render, db *gorm.DB){
activities := []models.Activity{}
db.Find(&activities)
fmt.Printf("%+v\n", activities)
render.HTML(200, "activities/index", activities)
}
func ShowActivity(params martini.Params, render render.Render, db *gorm.DB){
activity := models.Activity{}
db.First(&activity, params["id"])
render.HTML(200, "activities/show", activity)
}
func NewActivity(render render.Render){
render.HTML(200, "activities/new", models.Activity{})
}
func EditActivity(params martini.Params, render render.Render, db *gorm.DB){
activity := models.Activity{}
db.First(&activity, params["id"])
render.HTML(200, "activities/edit", activity)
}
func CreateActivity(params martini.Params, render render.Render, activity models.Activity, db *gorm.DB) {
db.Save(&activity)
render.Redirect("/activities/" + string(activity.ID), 302)
}
func UpdateActivity(params martini.Params, render render.Render, activity_updated models.Activity, db *gorm.DB) {
activity := models.Activity{}
db.First(&activity, params["id"])
db.Model(&activity).Updates(activity_updated)
render.Redirect("/activities/" + string(params["id"]), 302)
}
func DeleteActivity(params martini.Params, render render.Render, db *gorm.DB){
db.Delete(models.Activity{}, params["id"])
render.Redirect("/activities/", 302)
}
Just to wrap it up, we could define our migrations under config/migrations.go
, here is how would that looks like
About The Author
I am Pankaj Baagwan, a System Design Architect. A Computer Scientist by heart, process enthusiast, and open source author/contributor/writer. Advocates Karma. Love working with cutting edge, fascinating, open source technologies.
To consult Pankaj Bagwan on System Design, Cyber Security and Application Development, SEO and SMO, please reach out at me[at]bagwanpankaj[dot]com
For promotion/advertisement of your services and products on this blog, please reach out at me[at]bagwanpankaj[dot]com
Stay tuned <3. Signing off for RAAM