130 lines
3.1 KiB
Go
130 lines
3.1 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"api-soap-facturacion/internal/config"
|
|
"api-soap-facturacion/internal/logger"
|
|
"api-soap-facturacion/internal/soap"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
// NewRouter configura el router HTTP
|
|
func NewRouter(cfg *config.Config, log logger.Logger, db *sqlx.DB, soapClients *soap.Clients) *gin.Engine {
|
|
// Configurar modo de Gin según entorno
|
|
if cfg.App.Environment == "production" {
|
|
gin.SetMode(gin.ReleaseMode)
|
|
}
|
|
|
|
// Crear router
|
|
router := gin.New()
|
|
|
|
// Configurar middleware
|
|
router.Use(gin.Recovery())
|
|
router.Use(LoggerMiddleware(log))
|
|
router.Use(RequestIDMiddleware())
|
|
router.Use(CORSMiddleware())
|
|
|
|
// Configurar manejadores
|
|
handler := NewHandler(cfg, log, db, soapClients)
|
|
|
|
// Rutas de salud
|
|
router.GET("/health", handler.HealthCheck)
|
|
|
|
// Rutas API
|
|
api := router.Group("/api/v1")
|
|
{
|
|
// API1
|
|
api1 := api.Group("/api1")
|
|
{
|
|
api1.POST("/get-data", handler.API1GetData)
|
|
}
|
|
|
|
// API2
|
|
api2 := api.Group("/api2")
|
|
{
|
|
api2.POST("/process-transaction", handler.API2ProcessTransaction)
|
|
}
|
|
|
|
// Parámetros
|
|
params := api.Group("/parameters")
|
|
{
|
|
params.GET("", handler.GetAllParameters)
|
|
params.GET("/:key", handler.GetParameter)
|
|
params.PUT("/:key", handler.UpdateParameter)
|
|
}
|
|
}
|
|
|
|
return router
|
|
}
|
|
|
|
// LoggerMiddleware configura el middleware de logging
|
|
func LoggerMiddleware(log logger.Logger) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// Antes de la solicitud
|
|
path := c.Request.URL.Path
|
|
method := c.Request.Method
|
|
requestID := c.GetHeader("X-Request-ID")
|
|
|
|
// Crear logger para esta solicitud
|
|
reqLogger := log.With(
|
|
logger.NewField("request_id", requestID),
|
|
logger.NewField("path", path),
|
|
logger.NewField("method", method),
|
|
)
|
|
|
|
// Almacenar logger en el contexto
|
|
c.Set("logger", reqLogger)
|
|
|
|
reqLogger.Info("Solicitud iniciada")
|
|
|
|
// Procesar solicitud
|
|
c.Next()
|
|
|
|
// Después de la solicitud
|
|
status := c.Writer.Status()
|
|
reqLogger.Info("Solicitud completada",
|
|
logger.NewField("status", status),
|
|
)
|
|
}
|
|
}
|
|
|
|
// RequestIDMiddleware genera un ID único para cada solicitud
|
|
func RequestIDMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// Si no hay ID de solicitud, generar uno
|
|
requestID := c.GetHeader("X-Request-ID")
|
|
if requestID == "" {
|
|
requestID = generateRequestID()
|
|
c.Request.Header.Set("X-Request-ID", requestID)
|
|
}
|
|
|
|
// Establecer ID de solicitud en la respuesta
|
|
c.Writer.Header().Set("X-Request-ID", requestID)
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// CORSMiddleware configura CORS
|
|
func CORSMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
|
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
|
c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Request-ID")
|
|
|
|
if c.Request.Method == "OPTIONS" {
|
|
c.AbortWithStatus(http.StatusOK)
|
|
return
|
|
}
|
|
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// generateRequestID genera un ID único para una solicitud
|
|
func generateRequestID() string {
|
|
return "req-" + uuid.New().String()
|
|
}
|