Skip to content

Instantly share code, notes, and snippets.

@bonfy
Forked from linxlad/example.go
Created December 6, 2017 01:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bonfy/be346a6bef432c48ff37d7ba5fd97ef2 to your computer and use it in GitHub Desktop.
Save bonfy/be346a6bef432c48ff37d7ba5fd97ef2 to your computer and use it in GitHub Desktop.
simple DRY controller. golang github.com/labstack/echo example
package main
import (
"fmt"
"net/http"
"reflect"
"strconv"
"github.com/jinzhu/gorm"
"github.com/labstack/echo"
mw "github.com/labstack/echo/middleware"
_ "github.com/lib/pq"
)
var db gorm.DB
// User simple model
type User struct {
ID int `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
func init() {
var err error
db, err = gorm.Open("postgres", "user=gorm password=123 dbname=gorm sslmode=disable")
if err != nil {
panic(err)
}
}
func respond(c *echo.Context, err error, result interface{}) error {
var msg string
if err != nil {
msg = fmt.Sprint(err)
}
statusCode := http.StatusOK
switch err {
case gorm.RecordNotFound:
statusCode = http.StatusNotFound
case gorm.InvalidSql, gorm.NoNewAttrs, gorm.NoValidTransaction, gorm.CantStartTransaction:
statusCode = http.StatusInternalServerError
}
return c.JSON(statusCode, map[string]interface{}{
"result": result,
"error": err != nil,
"message": msg,
})
}
// DRYGetList get all objects from table
func DRYGetList(my interface{}) echo.Handler {
return func(c *echo.Context) error {
myType := reflect.TypeOf(my)
slice := reflect.MakeSlice(reflect.SliceOf(myType), 0, 0)
// Create a pointer to a slice value and set it to the slice
x := reflect.New(slice.Type())
x.Elem().Set(slice)
return respond(c, db.Find(x.Interface()).Error, x.Interface())
}
}
// DRYGetOne get one object from table by id
func DRYGetOne(my interface{}) echo.Handler {
return func(c *echo.Context) error {
myType := reflect.ValueOf(my).Elem()
x := reflect.New(myType.Type())
x.Elem().Set(myType)
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return respond(c, err, nil)
}
return respond(c, db.First(x.Interface(), id).Error, x.Interface())
}
}
// DRYCreate create object into table
func DRYCreate(my interface{}) echo.Handler {
return func(c *echo.Context) error {
myType := reflect.ValueOf(my).Elem()
x := reflect.New(myType.Type())
x.Elem().Set(myType)
if err := c.Bind(x.Interface()); err != nil {
return respond(c, err, nil)
}
return respond(c, db.Create(x.Interface()).Error, x.Interface())
}
}
// DRYEdit edit object by id
func DRYEdit(my interface{}) echo.Handler {
return func(c *echo.Context) error {
myType := reflect.ValueOf(my).Elem()
x := reflect.New(myType.Type())
x.Elem().Set(myType)
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return respond(c, err, nil)
}
if err := db.First(x.Interface(), id).Error; err != nil {
return respond(c, err, nil)
}
if err := c.Bind(x.Interface()); err != nil {
return respond(c, err, nil)
}
return respond(c, db.Save(x.Interface()).Error, x.Interface())
}
}
// DRYDestroy delete object by id
func DRYDestroy(my interface{}) echo.Handler {
return func(c *echo.Context) error {
myType := reflect.ValueOf(my).Elem()
x := reflect.New(myType.Type())
x.Elem().Set(myType)
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return respond(c, err, nil)
}
if err := db.First(x.Interface(), id).Error; err != nil {
return respond(c, err, nil)
}
return respond(c, db.Where("id = ?", id).Delete(x.Interface()).Error, x.Interface())
}
}
func main() {
app := echo.New()
app.Use(mw.Logger())
app.Use(mw.Recover())
app.Get("/", DRYGetList(&User{}))
app.Get("/:id", DRYGetOne(&User{}))
app.Post("/", DRYCreate(&User{}))
app.Patch("/:id", DRYEdit(&User{}))
app.Delete("/:id", DRYDestroy(&User{}))
app.Run(":3000")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment