mgoapi/register.go

106 lines
2.5 KiB
Go

package mgoapi
import (
"gitbase.de/gopackage/mgocrud"
"github.com/gin-gonic/gin"
mgo "gopkg.in/mgo.v2"
)
// API is wrapper for one RouterGroup and mgo DB
type API struct {
DBSession *mgo.Session
DBName string
routerGroup *gin.RouterGroup
jwtSecret []byte
authenticationHeader string
}
// Context is gin.Context with extras
type Context struct {
*gin.Context
API *API
DB *mgo.Database
}
// New returns new instance of the API
func New(session *mgo.Session, dbname string, routerGroup *gin.RouterGroup) *API {
return &API{
DBSession: session,
DBName: dbname,
routerGroup: routerGroup,
}
}
var modelRegistry = make([]mgocrud.ModelInterface, 0, 0)
// RegisterModel setups gin routes for model GET, POST, PUT and DELETE
func (api *API) RegisterModel(m mgocrud.ModelInterface) {
modelRegistry = append(modelRegistry, m)
session := api.DBSession.Copy()
defer session.Close()
db := session.DB(api.DBName)
err := mgocrud.EnsureIndex(db, m)
if err != nil {
panic(err)
}
cName := mgocrud.GetCollectionName(m)
colGroup := api.routerGroup.Group("/" + cName)
if i, ok := m.(interface {
Middleware(*Context)
}); ok {
colGroup.Use(func(c *gin.Context) {
i.Middleware(&Context{
Context: c,
API: api,
DB: db,
})
})
}
colGroup.GET("/:id", api.collectionGetOneHandler(m))
colGroup.GET("", api.collectionGetHandler(m))
colGroup.POST("", api.collectionPostHandler(m))
colGroup.PUT("/:id", api.collectionPutHandler(m))
colGroup.DELETE("/:id", api.collectionDeleteHandler(m))
}
// AddMetaRoute adds a route for retrieving meta information for all models
// call after all registerModel calls
func (api *API) AddMetaRoute(route string) {
api.routerGroup.GET(route, func(c *gin.Context) {
modelMeta := make(map[string]interface{})
for _, m := range modelRegistry {
modelMeta[mgocrud.GetCollectionName(m)] = getModelMeta(m)
}
c.JSON(200, map[string]interface{}{
"models": modelMeta,
})
})
for _, m := range modelRegistry {
api.routerGroup.GET("/_meta/"+mgocrud.GetCollectionName(m), api.collectionGetMetaHandler(m))
}
}
// LoginConfig configures login method
type LoginConfig struct {
JWTSecret []byte
AuthenticationHeader string
}
// AddLoginRoute adds a route for login
func (api *API) AddLoginRoute(route string, m LoginModel, c LoginConfig) {
api.jwtSecret = c.JWTSecret
api.authenticationHeader = c.AuthenticationHeader
api.routerGroup.POST(route, api.loginPostHandler(m))
}