Given you want to do web development, my recommendation is python/Django, absolutely.

Go is a nice language, but it is a “systems” language. It’s great for building databases, command line applications, kubernetes stuff, etc. Notice you are.comparing Go (a programming language) with Django (a framework). You don’t have the equivalent of django in Go, so you will have to mix and match a lot of libraries, build all the glue between them, etc. It is a lot of work.

I’m a frontend dev at work, and the backend team uses Go for building APIs. They struggle a lot to do things you would have basically for free with Django or ruby on rails. It is sad to see how much time and money they waste just because of using the wrong tool.

So, web dev? Use django, or rails, and/or JavaScript. Even nodejs has better libraries and ecosystem for webdev than Go.

Building a CLI? A Database server? A DNS server? A plugin for kubernetes? Use Go….right tool for the job.

sessions

Gin middleware for session management with multi-backend support (currently cookie, Redis, Memcached, MongoDB, memstore).

1
$ go get github.com/gin-contrib/sessions
1
import "github.com/gin-contrib/sessions"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import (
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	store := cookie.NewStore([]byte("secret"))
	r.Use(sessions.Sessions("mysession", store))

	r.GET("/incr", func(c *gin.Context) {
		session := sessions.Default(c)
		var count int
		v := session.Get("count")
		if v == nil {
			count = 0
		} else {
			count = v.(int)
			count++
		}
		session.Set("count", count)
		session.Save()
		c.JSON(200, gin.H{"count": count})
	})
	r.Run(":8000")
}

Redis-based Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import (
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/redis"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
	r.Use(sessions.Sessions("mysession", store))

	r.GET("/incr", func(c *gin.Context) {
		session := sessions.Default(c)
		var count int
		v := session.Get("count")
		if v == nil {
			count = 0
		} else {
			count = v.(int)
			count++
		}
		session.Set("count", count)
		session.Save()
		c.JSON(200, gin.H{"count": count})
	})
	r.Run(":8000")
}

Cache

Gin middleware/handler to enable Cache.

1
$ go get github.com/gin-contrib/cache
1
import "github.com/gin-contrib/cache"

Canonical example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import (
	"fmt"
	"time"

	"github.com/gin-contrib/cache"
	"github.com/gin-contrib/cache/persistence"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	store := persistence.NewInMemoryStore(time.Second)
	
	r.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong "+fmt.Sprint(time.Now().Unix()))
	})
	// Cached Page
	r.GET("/cache_ping", cache.CachePage(store, time.Minute, func(c *gin.Context) {
		c.String(200, "pong "+fmt.Sprint(time.Now().Unix()))
	}))

	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}

CORS

CSRF protection

JWT

Log