Tuesday, September 24, 2013

Go (golang), MVC and MongoDB, part 2

Now comes the fun part, the actual code. The first thing we need to do is configure the website. That consists of routes.go and config.go, both in src/gomgoweb. First we'll tackle the routes. Here is that file in full:
routes.go
// routes
package gomgoweb

import (
// "fmt"
"github.com/QLeelulu/goku"
)

// routes
var Routes []*goku.Route = []*goku.Route{
// static file route
&goku.Route{
Name:     "static",
IsStatic: true,
Pattern:  "/static/(.*)",
},
// default controller and action route
&goku.Route{
Name:    "default",
Pattern: "/{controller}/{action}/{id}",
Default: map[string]string{"controller": "home", "action": "index",
"id": "0"},
},
}

This file configures the two kinds of web addresses we'll be using. The "static" route is for things like JPEG files,or, in our case, a CSS file. The "default" route is for the MVC web addresses. As you probably guessed, the Default dictionary determines the home address of the website (/home/index).

Noe for the more difficult part, config.go. This contains the domain name of the website, as well as the site's behavior and global constants. Here is the whole thing:

config.go
// config
package gomgoweb

import (
"github.com/QLeelulu/goku"
"path"
"runtime"
"time"
)

var Config *goku.ServerConfig = &goku.ServerConfig{
Addr:           "localhost:8080",
ReadTimeout:    10 * time.Second,
WriteTimeout:   10 * time.Second,
MaxHeaderBytes: 1 << 20,
StaticPath:     "static",
ViewPath:       "views",
LogLevel:       goku.LOG_LEVEL_LOG,
Debug:          true,
}

const (
DATABASE     = "gomgoweb-8"
BAND_COL     = "bands"
LOCATION_COL = "locations"
GENRE_COL    = "genres"
ALBUM_COL    = "albums"
DATABASE_DSN = "localhost"
)

func init() {
// project root directory
_, filename, _, _ := runtime.Caller(1)
Config.RootDir = path.Dir(filename)
}

You could use just about any string for the database name. "COL" here is short for "collection". In MongoDB, data is first organized into databases, then into collections. "Addr" determines the domain name. In a real life website, this would more likely be a publicly accessed web address. This file also tells Goku where to find the view HTML files, as well as gives a potential alias for the the "static" directory.  

We of course need a main package and entry point. Those are provided by gomgoweb.go, which goes in the project's root directory. Here it is:

gomgoweb.go
// gomgoweb
package main

import (
// "fmt"
"github.com/QLeelulu/goku"
"gomgoweb"
"gomgoweb/controllers"
// "gomgoweb/models"
// "labix.org/v2/mgo/bson"
"log"
)

func main() {
// fmt.Println("Hello World!")
rt := &goku.RouteTable{Routes: gomgoweb.Routes}
middlewares := []goku.Middlewarer{}
s := goku.CreateServer(rt, middlewares, gomgoweb.Config)
goku.Logger().Logln("Server start on", s.Addr)
log.Fatal(s.ListenAndServe())
}

var home = controllers.HomeController
var band = controllers.BandController
var album = controllers.AlbumController

You can safely ignore the commented-out lines. As you can see, the main() function creates the web server in memory and connects it to the files we previously created. You also see that this file establishes the controllers as global variables. The names of those variables can be anything that's legal in Go. I did things this way for the sake of simple explanation. You could have created those variables in the controller files, given them empty ("_") names, and imported the controller package as _ "gomgoweb/controllers", but I think the way I coded it is more intuitive. The ListenAndServe() method is what actually starts the web server up.

At this point, if you left out all mention of controllers, this code would run. However, you wouldn't be able to view the results in your browser. For that, you need a controller and HTML template file. We'll create those soon. In the next installment, we'll get into other global aspects of this project: the CSS and the layout template.  

No comments:

Post a Comment