New
This commit is contained in:
167
internal/domain/upstream/handler.go
Normal file
167
internal/domain/upstream/handler.go
Normal file
@@ -0,0 +1,167 @@
|
||||
// Filename: internal/domain/upstream/handler.go
|
||||
package upstream
|
||||
|
||||
import (
|
||||
"gemini-balancer/internal/errors"
|
||||
"gemini-balancer/internal/models"
|
||||
"gemini-balancer/internal/response"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
service *Service
|
||||
}
|
||||
|
||||
func NewHandler(service *Service) *Handler {
|
||||
return &Handler{service: service}
|
||||
}
|
||||
|
||||
// ------ DTOs and Validation ------
|
||||
type CreateUpstreamRequest struct {
|
||||
URL string `json:"url" binding:"required"`
|
||||
Weight int `json:"weight" binding:"omitempty,gte=1,lte=1000"`
|
||||
Status string `json:"status" binding:"omitempty,oneof=active inactive"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
type UpdateUpstreamRequest struct {
|
||||
URL *string `json:"url"`
|
||||
Weight *int `json:"weight" binding:"omitempty,gte=1,lte=1000"`
|
||||
Status *string `json:"status" binding:"omitempty,oneof=active inactive"`
|
||||
Description *string `json:"description"`
|
||||
}
|
||||
|
||||
func isValidURL(rawURL string) bool {
|
||||
u, err := url.ParseRequestURI(rawURL)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return u.Scheme == "http" || u.Scheme == "https"
|
||||
}
|
||||
|
||||
// --- Handler ---
|
||||
|
||||
func (h *Handler) CreateUpstream(c *gin.Context) {
|
||||
var req CreateUpstreamRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, errors.NewAPIError(errors.ErrInvalidJSON, err.Error()))
|
||||
return
|
||||
}
|
||||
if !isValidURL(req.URL) {
|
||||
response.Error(c, errors.NewAPIError(errors.ErrValidation, "Invalid URL format"))
|
||||
return
|
||||
}
|
||||
|
||||
upstream := models.UpstreamEndpoint{
|
||||
URL: req.URL,
|
||||
Weight: req.Weight,
|
||||
Status: req.Status,
|
||||
Description: req.Description,
|
||||
}
|
||||
|
||||
if err := h.service.Create(&upstream); err != nil {
|
||||
response.Error(c, errors.ParseDBError(err))
|
||||
return
|
||||
}
|
||||
response.Created(c, upstream)
|
||||
}
|
||||
|
||||
func (h *Handler) ListUpstreams(c *gin.Context) {
|
||||
upstreams, err := h.service.List()
|
||||
if err != nil {
|
||||
response.Error(c, errors.ParseDBError(err))
|
||||
return
|
||||
}
|
||||
response.Success(c, upstreams)
|
||||
}
|
||||
|
||||
func (h *Handler) GetUpstream(c *gin.Context) {
|
||||
id, err := strconv.Atoi(c.Param("id"))
|
||||
if err != nil {
|
||||
response.Error(c, errors.NewAPIError(errors.ErrBadRequest, "Invalid ID format"))
|
||||
return
|
||||
}
|
||||
|
||||
upstream, err := h.service.GetByID(id)
|
||||
if err != nil {
|
||||
response.Error(c, errors.ParseDBError(err))
|
||||
return
|
||||
}
|
||||
response.Success(c, upstream)
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateUpstream(c *gin.Context) {
|
||||
id, err := strconv.Atoi(c.Param("id"))
|
||||
if err != nil {
|
||||
response.Error(c, errors.NewAPIError(errors.ErrBadRequest, "Invalid ID format"))
|
||||
return
|
||||
}
|
||||
var req UpdateUpstreamRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, errors.NewAPIError(errors.ErrInvalidJSON, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
upstream, err := h.service.GetByID(id)
|
||||
if err != nil {
|
||||
response.Error(c, errors.ParseDBError(err))
|
||||
return
|
||||
}
|
||||
|
||||
if req.URL != nil {
|
||||
if !isValidURL(*req.URL) {
|
||||
response.Error(c, errors.NewAPIError(errors.ErrValidation, "Invalid URL format"))
|
||||
return
|
||||
}
|
||||
upstream.URL = *req.URL
|
||||
}
|
||||
if req.Weight != nil {
|
||||
upstream.Weight = *req.Weight
|
||||
}
|
||||
if req.Status != nil {
|
||||
upstream.Status = *req.Status
|
||||
}
|
||||
if req.Description != nil {
|
||||
upstream.Description = *req.Description
|
||||
}
|
||||
|
||||
if err := h.service.Update(upstream); err != nil {
|
||||
response.Error(c, errors.ParseDBError(err))
|
||||
return
|
||||
}
|
||||
response.Success(c, upstream)
|
||||
}
|
||||
|
||||
func (h *Handler) DeleteUpstream(c *gin.Context) {
|
||||
id, err := strconv.Atoi(c.Param("id"))
|
||||
if err != nil {
|
||||
response.Error(c, errors.NewAPIError(errors.ErrBadRequest, "Invalid ID format"))
|
||||
return
|
||||
}
|
||||
|
||||
rowsAffected, err := h.service.Delete(id)
|
||||
if err != nil {
|
||||
response.Error(c, errors.ParseDBError(err))
|
||||
return
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
response.Error(c, errors.ErrResourceNotFound)
|
||||
return
|
||||
}
|
||||
response.NoContent(c)
|
||||
}
|
||||
|
||||
// RegisterRoutes
|
||||
|
||||
func (h *Handler) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
upstreamRoutes := rg.Group("/upstreams")
|
||||
{
|
||||
upstreamRoutes.POST("/", h.CreateUpstream)
|
||||
upstreamRoutes.GET("/", h.ListUpstreams)
|
||||
upstreamRoutes.GET("/:id", h.GetUpstream)
|
||||
upstreamRoutes.PUT("/:id", h.UpdateUpstream)
|
||||
upstreamRoutes.DELETE("/:id", h.DeleteUpstream)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user