Useful utilities for reducing dependencies and improving performance within Cloudment Go projects.
go get github.com/cloudment/utils-go
Before we required both joho/godotenv
and caarlos0/env
to parse environment variables and store them in a struct.
However, this package eliminates the need for both, in a faster and simpler way.
There are plans to move this package to its own repository in the future. Including support for json, yml, toml, ini, csv, and pkl configuration files. Maybe support for providers such as S3 (Read a file from S3 and parse it into a struct).
In order to read a .env
, parse, and store it in a struct, we would need to use both libraries.
Library Function |
Benchmark time | Change / Percentage Difference |
---|---|---|
joho/godotenv Load() |
22,207 ns/op | N/A |
cloudment/utils-go ParseFromFileIntoStruct() |
9,013 ns/op | 13,194 ns/op quicker 84% |
caarlos0/env Parse() |
4,750 ns/op | N/A |
cloudment/utils-go Parse() |
2,971 ns/op | 1,779 ns/op quicker 46% |
Note: joho/godotenv
tests were done including caarlos0/env
as it is required to parse the .env
file and store it in a struct.
package main
import (
"fmt"
"github.com/cloudment/utils-go/env"
)
type Config struct {
Port int `env:"PORT" envDefault:"8080"`
}
func main() {
// with just os.Environ()
var cfg Config
env.Parse(&cfg)
fmt.Println(cfg.Port)
// with both os.Environ() and a .env file
var cfg2 Config
_ = env.ParseFromFileIntoStruct(&cfg2, ".env") // uses os.Environ() and .env file
fmt.Println(cfg.Port)
}
This allows you to bind a request to a struct, which is useful for APIs.
package main
import (
"net/http"
"github.com/cloudment/utils-go/utils"
)
type Request struct {
Field1 string `query:"field1" form:"field1" json:"field1" required:"true"`
Field2 string `query:"field2" form:"field2" json:"field2"`
}
func handler(w http.ResponseWriter, r *http.Request) {
var req Request
if err := BindRequest(r, &req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
This would allow you to specify multiple query parameters and generate a query for GORM.
If both ID
and Array
are provided, the query would be (id = ? AND ? = ANY(array))
. If not, it only uses 1.
This could be used to allow someone to search for a name
, id
, rank
, etc. in a database or all 3 at once.
package main
import (
"github.com/cloudment/utils-go/utils"
)
type OptionalQueryParams struct {
ID string `query:"id = ?"`
Array string `query:"? = ANY(array)"`
}
func main() {
// Ignore this, it's just an example
db, _ := pretendARealDatabaseConnection().ToARealDatabase().ToARealTable()
params := OptionalQueryParams{ID: "123", Array: "type1"}
query, args := GormSearchQuery(params)
// query = "(id = ? AND ? = ANY(array))"
// args = ["123", "type1"]
// Now you can use this query and args in your GORM query,
// in this example it would require the ID to be 123 and the Array to contain "type1"
db = db.Where(query, args...).Find(&results)
}