我正在使用GraphQL和go-pg。
我有很多这样的实体:
type Player struct {
ID int
CreatedAt time.Time `pg:"default:now(),notnull"`
TeamID int `pg:",notnull"`
Team *Team
Type int
Score int64 `pg:",notnull"`
Note *string
// and others...
}
type PlayerInput struct {
TeamID int
Type int
Score int64
Note *string
// and others...
}
我有很多类似的功能:
func (db *postgres) Update(context context.Context, id int, input types.PlayerInput) (*types.Player, error) {
var actualPlayer types.Player
newPlayer := graphqlToDB(&input)
tx, err := db.Begin()
//handle err
err = tx.Model(&actualPlayer).Where("id = ?", id).For("UPDATE").Select()
// handle err and rollback
actualPlayer.TeamID = newPlayer.TeamID
actualPlayer.Type = newPlayer.Type
actualPlayer.Score = newPlayer.Score
actualPlayer.Note = newPlayer.Note
// and others...
_, err = tx.Model(&actualPlayer).WherePK().Update()
// handle err and rollback
err = tx.Commit()
//handle err
return &actualPlayer, nil
}
func graphqlToDB(input *types.PlayerInput) *types.Player {
var output = &types.Player{
TeamID: input.TeamID,
Type: input.Type,
Score: input.Score,
Note: input.Note,
// and others...
}
if input.Type == "example" {
output.Score = 10000000
}
return output
}
我为项目中的每个实体都有此代码,我想限制/避免冗余代码,特别是:
每次从Graphql输入类型转换
newPlayer := graphqlToDB(&input)
actualPlayer.TeamID = newPlayer.TeamID
actualPlayer.Type = newPlayer.Type
actualPlayer.Score = newPlayer.Score
actualPlayer.Note = newPlayer.Note
tx, err := db.Begin()
我要月亮吗?
最佳答案
我认为这段代码中没有多余的冗余。
每次时从Graphql输入类型转换
将结构从外部模型转换为内部模型是一种常见的模式,有助于分离关注点。此外,您已经拥有
graphqlToDB
函数,该函数可让您在其主体中重用10行代码。那可能是最好的。在此处显示的特定代码段中,
actualPlayer
的类型为types.Player
,并且graphqlToDB
函数返回*types.Player
对象。因此,您可以简单地编写
actualPlayer := graphqlToDB(&input)
,然后像tx.Model(actualPlayer)
一样传递指针。这将重新映射
newPlayer
保存为actualPlayer
如果需要每次以事务方式访问数据库,则需要每次都打开事务(然后提交/回滚)。这是没有多余的。重构可能会导致可读性下降。