Serving Static HTML in Gin

Adler @ 2016-04-03


Gin is a web framework in Go. It serves to offer a better control of requests, responses, and routing, basically like Sinatra in Ruby.

The Basics

It is easy to initiate a server and render the content we disinate:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    r := gin.Default()
    r.GET("/hello", func(c *gin.Context) {
        c.String(http.StatusOK, "Hello from %v", "Gin")
    })
    r.Run(":3000")
}

Run go run main.go, and it should listen to port 3000 now. Go to the browser, open http://localhost:3000, and it should be there.

However, some points to explain in the code:

  • We import the Gin package but we still need the built-in net/http package for rendering http status code.
  • Gin offers two methods to start:
    • Default() method starts with built-in functions to serve static assets and others.
    • New() method is for advanced users who want to start from scratch.
  • We use GET to assign handler to the / route, followed by a handler function.
  • In the handler function we set the response using String() which set the content type as Plain/Text, after that is the text we want to serve.
  • Finally there is Run() method to start the server. It wraps the built-in ListenAndServe function.

Rendering HTML Files

It's easy, right? Now we can step a little further to render static files in our directory. Let's say we have the following structure.

- src
  - main.go
- templates
  - index.html
  - login.html
  - admin-overview.html

We can tell the program to render the files when the requests contain specific patterns.

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    r := gin.Default()
    r.LoadHTMLGlob("templates/**/*.html")
    r.GET("/", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.html", nil)
    })
    r.GET("/login", func(c *gin.Context) {
        c.HTML(http.StatusOK, "login.html", nil)
    })
    admin := r.Group("/admin")
    admin.GET("/", func(c *gin.Context) {
        c.HTML(http.StatusOK, "admin-overview.html", nil)
    })
    r.Run(":3000")
}
  • Use LoeadHTMLGlob() and specify a pattern for loading all HTML files when the server starts.
  • In response, we use HTML() to set the content type as HTML, followed by the status code, rendered file, and the injected data. Currently we don't have any data so we set it as nil.
  • Group("/admin") is to group all routes under a specific pattern. It works like namespace in Rails. All patterns set under this group will be prefixed with this pattern. For example, admin.GET("/login") will match the pattern /admin/login.

That's it. Hope you got an idea on how to start a Gin project!