mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
Implement handlers for creating, listing, and updating model bindings. Register new routes in the admin server group and add DTO definitions. Update provider handlers to trigger binding synchronization on changes to ensure upstream mappings remain current.
161 lines
4.4 KiB
Go
161 lines
4.4 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/ez-api/ez-api/internal/dto"
|
|
"github.com/ez-api/ez-api/internal/model"
|
|
groupx "github.com/ez-api/foundation/group"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// CreateBinding godoc
|
|
// @Summary Create a new binding
|
|
// @Description Create a new (namespace, public_model) binding to a route group and selector
|
|
// @Tags admin
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security AdminAuth
|
|
// @Param binding body dto.BindingDTO true "Binding Info"
|
|
// @Success 201 {object} model.Binding
|
|
// @Failure 400 {object} gin.H
|
|
// @Failure 500 {object} gin.H
|
|
// @Router /admin/bindings [post]
|
|
func (h *Handler) CreateBinding(c *gin.Context) {
|
|
var req dto.BindingDTO
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
ns := strings.TrimSpace(req.Namespace)
|
|
pm := strings.TrimSpace(req.PublicModel)
|
|
if ns == "" || pm == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "namespace and public_model required"})
|
|
return
|
|
}
|
|
|
|
rg := groupx.Normalize(req.RouteGroup)
|
|
if strings.TrimSpace(rg) == "" {
|
|
rg = "default"
|
|
}
|
|
|
|
st := strings.TrimSpace(req.Status)
|
|
if st == "" {
|
|
st = "active"
|
|
}
|
|
|
|
selectorType := strings.TrimSpace(req.SelectorType)
|
|
if selectorType == "" {
|
|
selectorType = "exact"
|
|
}
|
|
|
|
b := model.Binding{
|
|
Namespace: ns,
|
|
PublicModel: pm,
|
|
RouteGroup: rg,
|
|
SelectorType: selectorType,
|
|
SelectorValue: strings.TrimSpace(req.SelectorValue),
|
|
Status: st,
|
|
}
|
|
|
|
if err := h.db.Create(&b).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create binding", "details": err.Error()})
|
|
return
|
|
}
|
|
|
|
if err := h.sync.SyncBindings(h.db); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to sync bindings", "details": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, b)
|
|
}
|
|
|
|
// ListBindings godoc
|
|
// @Summary List bindings
|
|
// @Description List all configured bindings
|
|
// @Tags admin
|
|
// @Produce json
|
|
// @Security AdminAuth
|
|
// @Success 200 {array} model.Binding
|
|
// @Failure 500 {object} gin.H
|
|
// @Router /admin/bindings [get]
|
|
func (h *Handler) ListBindings(c *gin.Context) {
|
|
var out []model.Binding
|
|
if err := h.db.Find(&out).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to list bindings", "details": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, out)
|
|
}
|
|
|
|
// UpdateBinding godoc
|
|
// @Summary Update a binding
|
|
// @Description Update an existing binding
|
|
// @Tags admin
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security AdminAuth
|
|
// @Param id path int true "Binding ID"
|
|
// @Param binding body dto.BindingDTO true "Binding Info"
|
|
// @Success 200 {object} model.Binding
|
|
// @Failure 400 {object} gin.H
|
|
// @Failure 404 {object} gin.H
|
|
// @Failure 500 {object} gin.H
|
|
// @Router /admin/bindings/{id} [put]
|
|
func (h *Handler) UpdateBinding(c *gin.Context) {
|
|
idParam := c.Param("id")
|
|
id, err := strconv.Atoi(idParam)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
|
|
return
|
|
}
|
|
|
|
var existing model.Binding
|
|
if err := h.db.First(&existing, id).Error; err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "binding not found"})
|
|
return
|
|
}
|
|
|
|
var req dto.BindingDTO
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if ns := strings.TrimSpace(req.Namespace); ns != "" {
|
|
existing.Namespace = ns
|
|
}
|
|
if pm := strings.TrimSpace(req.PublicModel); pm != "" {
|
|
existing.PublicModel = pm
|
|
}
|
|
if rg := strings.TrimSpace(req.RouteGroup); rg != "" {
|
|
existing.RouteGroup = groupx.Normalize(rg)
|
|
}
|
|
if st := strings.TrimSpace(req.Status); st != "" {
|
|
existing.Status = st
|
|
}
|
|
if t := strings.TrimSpace(req.SelectorType); t != "" {
|
|
existing.SelectorType = t
|
|
}
|
|
if req.SelectorValue != "" {
|
|
existing.SelectorValue = strings.TrimSpace(req.SelectorValue)
|
|
}
|
|
|
|
if err := h.db.Save(&existing).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update binding", "details": err.Error()})
|
|
return
|
|
}
|
|
|
|
if err := h.sync.SyncBindings(h.db); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to sync bindings", "details": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, existing)
|
|
}
|
|
|