go-struct2serve
This is a small library for echo v4 that has a generic repository for accessing the database and populating structures in golang and has a generic controller and service.
You can create a custom repository or custom controller using Go compose.
Question
- Why Echo? Becouse It is my favorite framwork for make web apps :P.
- Why SQL? I love SQL.
- Can you add feature? yes, I love you ;).
- Why did I make this library? Because I have free time, but it doesn't mean I don't love GORM :).
- Why make this project? This project is a hobby and We use it in some minor projects. This is fun.
Example
user_model.go
package models
type User struct {
UserID int `json:"id" db:"id" s2s_id:"true"` // mark this field as id with tag s2s_id:"true"
FirstName string `json:"first_name" db:"first_name"`
Email string `json:"email" db:"email"`
Roles *[]Role `json:"roles,omitempty" s2s:"id in (select role_id from user_roles where user_id = ?)"` // not use s2s_param becuase s2s_param is the id of Struct
GroupId *int `json:"-" db:"group_id" s2s_update_value:"Group.ID"` // mark this field as id with tag s2s_update_value:"Group.ID" because json not send nil values json:"-"
Group *Group `json:"group,omitempty" s2s:"id = ?" s2s_param:"GroupId"` // use s2s_param becuase we need use GroupId value
//other way is Group *Group `json:"group,omitempty" s2s:"select * from groups where id = ?" sql_param:"GroupId"`
}
role_model.go
package models
type Role struct {
ID int `json:"id" db:"id" s2s_table_name:"roles"` // use s2s_table_name:"roles" because table name is not the same as struct name
Name string `json:"name" db:"name"`
Users *[]User `json:"users,omitempty" s2s:"id in (select user_id from user_roles where role_id = ?)"` // not use s2s_param becuase s2s_param is the id of Struct
}
group_model.go
package models
type Group struct {
ID int `json:"id" db:"id" s2s_table_name:"groups"` // use s2s_table_name:"groups" because table name is not the same as struct name
Name string `json:"name" db:"name"`
Users *[]User `json:"users,omitempty" s2s:"group_id = ?"` // not use s2s_param becuase s2s_param is the id of Struct
}
Example custom repository
user_repositories.go
- The project is "springhub" and the folder models is springhub/models
package customs
import (
"context"
"fmt"
"log"
"github.com/arturoeanton/go-struct2serve/config"
"github.com/arturoeanton/go-struct2serve/repositories"
"github.com/arturoeanton/springhub/models"
)
type UserRepository struct {
repositories.Repository[models.User]
}
func NewUserRepository() *UserRepository {
return &UserRepository{
Repository: *repositories.NewRepository[models.User](),
}
}
func (ur *UserRepository) GetAll() ([]*models.User, error) {
fmt.Println("Custom GetAll")
conn, err := config.DB.Conn(context.Background())
if err != nil {
return nil, err
}
defer conn.Close()
query := "SELECT * FROM user"
rows, err := conn.QueryContext(context.Background(), query)
if err != nil {
log.Printf("Error al ejecutar la consulta: %v", err)
return nil, err
}
defer rows.Close()
users := []*models.User{}
for rows.Next() {
user := &models.User{}
err := rows.Scan(&user.ID, &user.FirstName, &user.Email)
if err != nil {
log.Printf("Error al escanear la fila: %v", err)
return nil, err
}
users = append(users, user)
}
return users, nil
}
Example custom handler
project_handlers.go
- The project is "springhub" and the folder models is springhub/models
package customs
import (
"net/http"
"github.com/arturoeanton/go-struct2serve/handlers"
"github.com/arturoeanton/go-struct2serve/repositories"
"github.com/arturoeanton/go-struct2serve/services"
"github.com/arturoeanton/springhub/models"
"github.com/labstack/echo/v4"
)
type ProjectHandler struct {
*handlers.Handler[models.Project]
projectService services.IService[models.Project]
}
func NewProjectHandler() *ProjectHandler {
return &ProjectHandler{
Handler: handlers.NewHandler[models.Project](),
projectService: services.NewService[models.Project](
repositories.NewRepository[models.Project](),
),
}
}
func (uh *ProjectHandler) FilterByNameOrDesciption(c echo.Context) error {
name := c.QueryParam("name")
description := c.QueryParam("description")
projects, err := uh.projectService.GetByCriteria("name like ? or description like ? ", "%"+name+"%", "%"+description+"%")
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{
"error": "Failed to get projects",
})
}
return c.JSON(http.StatusOK, projects)
}