Sharing a Database Connection in “go-fiber”

My approach to routing a variable within a go-fiber app.

Image by Matt Duncan via unsplash

go-fiber is a Go web framework. It is inspired by ExpressJS, and after using it, the resemblance is uncanny. ExpressJS, if you didn’t know, is a web framework developed for NodeJS. It simplifies routing and the processing of HTTP requests. Coming from a NodeJS background, go-fiber seems like a good choice to build an API with. In this post, I’ll detail my approach to sharing a variable with my request handlers.

The Boilerplate

Starting an API server with go-fiber is quite simple. The following code will register an endpoint at the root of the server and begin listening at port 3000 :

package main
import "github.com/gofiber/fiber/v2"
func main() {
app := fiber.New()
 app.Get("/", func(c *fiber.Ctx) error {
    // writes Hello, World as output
return c.SendString("Hello, World!")
})
 app.Listen(":3000")
}

For this post, I’ll define a custom type called Database . This will be the type I’ll be sharing with my HTTP handlers. Here is the definition of this type :

type Database struct {
Name string
}
func (d *Database) Get() string {
return d.Name
}

To abstract storing and retrieving the data, I’ll define two generic functions. By employing generics, I’ll avoid processing any interface{} types within my HTTP handlers. Here is the definition of both functions :

func SetLocal[T any](c *fiber.Ctx, key string, value T) {
c.Locals(key, value)
}
func GetLocal[T any](c *fiber.Ctx, key string) T {
return c.Locals(key).(T)
}

As you can see, I’m relying on fiber.Ctx.Locals to store and get a variable. Next, I’ll implement a middleware function to store the database variable for each request. The variable will be stored with function SetLocal. The middleware function will be defined within the main function. Here is a revised version of function main :

func main() {

app := fiber.New()
db := Database{"Virtual_DB"}
 app.Use(func(c *fiber.Ctx) error {
  SetLocal[Database](c, "db", db)
// Go to next middleware:
return c.Next()
})
 app.Get("/", GetRoot)
 app.Listen(":3000")
}

If you noticed, I refactored my root handler to use function GetRoot . This is where storing the database as a local variable shines. Since GetRoot is not in the main function scope, it can’t access the db variable I’ve defined there.

I must be able to retrieve it without a global variable. This is possible with fiber.Ctx.Locals. Here is the definition of function GetRoot :

func GetRoot(c *fiber.Ctx) error {
 db := GetLocal[Database](c, "db")
fmt.Println(db.Get())
 return c.SendString("Hello, World!")
}

Here is this code in action :


Sharing a Database Connection in “go-fiber” was originally published in Better Programming on Medium, where people are continuing the conversation by highlighting and responding to this story.

0
(Visited 1 times, 1 visits today)