Awesome
Api with Echo + gorm
Configs
Describe with struct your config for project.
type Config struct {
Server struct {
Host string `json:"host"`
Port string `json:"port"`
IsProduction bool `json:"is_production"`
PasswordSalt []byte `json:"password_salt"`
JwtSecret []byte `json:"jwt_secret"`
Debug bool `json:"debug"`
} `json:"server"`
Postgres struct {
Host string `json:"host"`
Port string `json:"port"`
User string `json:"user"`
Password string `json:"password"`
DB string `json:"db"`
} `json:"postgres"`
}
And use file.json for value to config.
{
"server": {
"host": "0.0.0.0",
"port": "8080",
"jwt_secret": "mysecret",
"password_salt": "mysalted",
"debug": false
},
"postgres": {
"host": "localhost",
"port": "5432",
"user": "backend",
"password": "mypass",
"db": "backend"
}
}
You can specific the path of file with flag 'config', in server.go read this flag.
configPath := flag.String("config", "./config/production.json", "path of the config file")
flag.Parse()
// Read config
config, err := config.FromFile(*configPath)
if err != nil {
log.Fatal(err)
}
And you can use configs.GetConfig() for get configs, example models/user.go
func (u *User) SetPassword() {
cfg := config.GetConfig()
key := argon2.Key([]byte(u.Password), cfg.Server.PasswordSalt, 3, 32*1024, 4, 32)
u.Password = hex.EncodeToString(key)
}
Models
Contains the data structures used for communication between different layers, using gorm.
type User struct {
gorm.Model
RoleID uint `gorm:"index;not null;default:'2'" json:"role_id,omitempty" valid:"int, required"`
FirstName string `gorm:"type:varchar(155);not null" json:"first_name,omitempty" valid:"required"`
LastName string `gorm:"type:varchar(155);not null" json:"last_name,omitempty" valid:"required"`
....
}
Repositories
Using repository pattern for separated the logic.
The base Repository{} has functions common like:
func (r *Repository) Find(model interface{}, filter, value string) bool {. .. }
func (r *Repository) Save(model interface{}) bool { ... }
You can create new repo that inherit of this.
type UserRepository struct {
*Repository
}
func NewUserRepo(db *gorm.DB) *UserRepository {
return &UserRepository{&Repository{db}}
}
func (ur *UserRepository) FindByCredentials(user *models.User) bool {
if ur.DB.Where("email = ? and password = ?", user.Email, user.Password).First(&user).RecordNotFound() {
return false
}
return true
}
Resources
contains the API layer that wires up the HTTP routes with the corresponding service APIs.
type UserController struct{}
func (uc *UserController) Register(c echo.Context) error {...}
func (uc *UserController) Login(c echo.Context) error {...}
Routes
Register your in routes/base.go
func Init(e *echo.Echo) {
RegisterUser(e)
}
describes routes for your resources.
func RegisterUser(e *echo.Echo) {
userController := new(resources.UserController)
e.POST("auth/register", userController.Register)
e.POST("auth/login", userController.Login)
}
Midlewares
Put here your custom middlewares.
We create middleware for put DB to context.
func DBMiddleware(db *gorm.DB) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.Set("db", db)
next(c)
return nil
}
}
}
Databases
Manage connection and logic for dbs.
Helpers
Put here your helpers functions.