我正在使用 GoFiber 创建一个 Go 服务器来从 MySQL 数据库返回数据。我正在使用 GORM 库来保存和从数据库中获取数据。我总共有 8 个实体。我已经为这些实体定义了模型,如下所示
package models
type Account struct {
ID uint `json:"id" gorm:"primary_key;auto_increment;not_null"`
Name string `json:"name"`
Company string `json:"company"`
GSTIN string `json:"gstin"`
AccountNo string `json:"accountNo" gorm:"unique"`
IFSC string `json:"ifsc"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
现在,对于每个实体,我正在编写 4 个控制器方法:创建、更新、列表、删除。每个实体的代码基本上相同,只是实体名称发生了变化。
package controllers
// GET: List call
func GetAccounts(c *fiber.Ctx) error {
accounts := new([]models.Account)
result := database.DB.Find(accounts)
if result.Error != nil {
return result.Error
}
c.SendStatus(http.StatusOK)
return c.JSON(accounts)
}
// POST
func CreateAccount(c *fiber.Ctx) error {
account := new(models.Account)
err := c.BodyParser(account)
if err != nil {
return err
}
result := database.DB.Create(account)
if result.Error != nil{
return result.Error
}
return c.SendStatus(http.StatusCreated)
}
现在,像这样,我已经编写了 8 x 4 =32 个控制器方法。所有代码都有重复的代码,只是实体名称发生了变化。
我还手动为每个控制器定义了路线。
app.Post("api/account", controllers.CreateAccount)
app.Get("api/accounts", controllers.GetAccounts)
肯定有更好的方法来做到这一点。我不太确定如何这样做或实施它。我应该定义哪些接口,应该嵌入哪些结构,或者做什么?
您可以使用泛型。请参阅下面的示例。
T
代表要创建的数据类型。
func Create[T any](c *fiber.Ctx, data T) error {
result := database.DB.Create(data)
if result.Error != nil {
return result.Error
}
return nil
}
你可以这样做:
func Get[T any]() fiber.Handler {
return func(c *fiber.Ctx) error {
models := new([]T)
result := database.DB.Find(models)
if result.Error != nil {
return result.Error
}
c.SendStatus(http.StatusOK)
return c.JSON(models)
}
}
func Create[T any]() fiber.Handler {
return func(c *fiber.Ctx) error {
model := new(T)
err := c.BodyParser(model)
if err != nil {
return err
}
result := database.DB.Create(model)
if result.Error != nil{
return result.Error
}
return c.SendStatus(http.StatusCreated)
}
}
然后对于路由,您必须以这种方式调用处理程序:
app.Post("api/account", controllers.Create[models.Account]())
app.Get("api/accounts", controllers.Get[models.Account]())