Я пишу простой API в Go, используя github.com/gin-gonic/gin
. Он поддерживается базой данных, и я использую github.com/jinzhu/gorm
для запросов и обновления базы данных.
У меня есть несколько конечных точек, которые в значительной степени используют один и тот же код для получения данных из базы данных, поэтому я пытаюсь создать один retrieve
метод, который работает со всеми моими типами БД.
Так, например, у меня есть следующая структура:
type Image struct {
gorm.Model
Name string
Filename string
}
Объявление API для моего маршрута: следующим образом:
func (v1 *ApiV1) getImage(c *gin.Context) {
var images []db.Image
httpStatus := v1.retrieve("name", c.Param("name"), &images)
c.JSON(
httpStatus,
images,
)
}
Как видно, я пытаюсь передать указатель на структуру, которую я хочу заполнить запросом. Поскольку мне понадобятся несколько различных представлений для разных типов в БД, я хочу сделать метод retrieve
повторно используемым, поэтому я создал его с такой подписью:
func (v1 *ApiV1) retrieve(fieldName string, name string, returnObject *[]interface{}) int {
// create var to hold the http status
var httpStatus int = http.StatusOK
// determine if a name has been passed
if name == "" {
v1.app.DB.Find(returnObject)
} else {
// look for the name in the database
v1.app.DB.Where(fieldName+" = ?", name).First(returnObject)
// if the name cannot be found then set the status to 404
if len(*returnObject) == 0 {
httpStatus = http.StatusNotFound
}
}
return httpStatus
}
Чтобы попытаться сделать его 'обобщенным c 'Я использовал *[]interface{}
в качестве типа для returnObject. (Имя немного неправильное, так как оно указатель, но оно позволяет легко понять, что что-то будет обновлено).
Однако, когда я запускаю это, я получаю следующую ошибку:
cannot use &images (type *[]db.Image) as type *[]interface {} in argument to v1.retrieve
Я полностью понимаю, что Go является строго типизированным языком, но, поскольку я хочу иметь возможность повторно использовать мою retrieve
функцию, мне нужно иметь возможность передавать указатель на фрагмент (любого типа), который Gorm может заполняться при выполнении запроса.
Я в настоящее время рефакторинг этого из версии, которая имела отдельную функцию для извлечения для каждой из конечных точек API, но очевидно, что это неэффективно и затрудняет выполнение любых refactor.
Так что же я спрашиваю вообще возможно?