A:增加HTTP基础功能的访问和HTTP模板

This commit is contained in:
jimmy committed 2025-06-14 00:38:20 +08:00
1 parent e4de5917cd
commit f67e27320f
11 files changed
+620 -6

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
package handler
import (
"github.com/gin-gonic/gin"
"net/http"
"rear/internal/model"
"time"
)
// HealthCheck 健康检查
func HealthCheck(c *gin.Context) {
c.JSON(http.StatusOK, model.Response{
Code: http.StatusOK,
Message: "OK",
Data: map[string]interface{}{
"timestamp": time.Now().Unix(),
"version": "1.0.0",
},
})
}
// BasicResponse 健康检查
func BasicResponse(c *gin.Context) {
c.JSON(http.StatusOK, model.Response{
Code: http.StatusOK,
Message: "OK",
Data: map[string]interface{}{
"timestamp": time.Now().Unix(),
"version": "1.0.0",
},
})
}
+138
View File
@@ -0,0 +1,138 @@
package handler
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"rear/internal/model"
)
// 全局变量
var (
Users []model.User // 模拟数据存储
userNextID = 1
)
// DeleteUser 删除用户
func DeleteUser(c *gin.Context) {
id := c.Param("id")
for i, user := range Users {
if fmt.Sprintf("%d", user.ID) == id {
Users = append(Users[:i], Users[i+1:]...)
c.JSON(http.StatusOK, model.Response{
Code: http.StatusOK,
Message: "User deleted successfully",
})
return
}
}
c.JSON(http.StatusNotFound, model.Response{
Code: http.StatusNotFound,
Message: "User not found",
})
}
// GetUserByID 根据ID获取用户
func GetUserByID(c *gin.Context) {
id := c.Param("id")
for _, user := range Users {
if fmt.Sprintf("%d", user.ID) == id {
c.JSON(http.StatusOK, model.Response{
Code: http.StatusOK,
Message: "Success",
Data: user,
})
return
}
}
c.JSON(http.StatusNotFound, model.Response{
Code: http.StatusNotFound,
Message: "User not found",
})
}
// InitSampleData 初始化示例数据
func InitSampleData() {
Users = []model.User{
{ID: 1, Name: "John Doe", Email: "john@example.com"},
{ID: 2, Name: "Jane Smith", Email: "jane@example.com"},
}
userNextID = 3
}
// UpdateUser 更新用户
func UpdateUser(c *gin.Context) {
id := c.Param("id")
for i, user := range Users {
if fmt.Sprintf("%d", user.ID) == id {
var updatedUser model.User
if err := c.ShouldBindJSON(&updatedUser); err != nil {
c.JSON(http.StatusBadRequest, model.Response{
Code: http.StatusBadRequest,
Message: "Invalid request body",
})
return
}
updatedUser.ID = user.ID
Users[i] = updatedUser
c.JSON(http.StatusOK, model.Response{
Code: http.StatusOK,
Message: "User updated successfully",
Data: updatedUser,
})
return
}
}
c.JSON(http.StatusNotFound, model.Response{
Code: http.StatusNotFound,
Message: "User not found",
})
}
// GetUsers 获取所有用户
func GetUsers(c *gin.Context) {
c.JSON(http.StatusOK, model.Response{
Code: http.StatusOK,
Message: "Success",
Data: Users,
})
}
// CreateUser 创建用户
func CreateUser(c *gin.Context) {
var user model.User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, model.Response{
Code: http.StatusBadRequest,
Message: "Invalid request body",
})
return
}
// 简单验证
if user.Name == "" || user.Email == "" {
c.JSON(http.StatusBadRequest, model.Response{
Code: http.StatusBadRequest,
Message: "Name and email are required",
})
return
}
user.ID = userNextID
userNextID++
Users = append(Users, user)
c.JSON(http.StatusCreated, model.Response{
Code: http.StatusCreated,
Message: "User created successfully",
Data: user,
})
}
+26
View File
@@ -0,0 +1,26 @@
package model
import (
"rear/internal/utils"
"time"
)
// Config 配置结构
type Config struct {
Port string
Mode string
ReadTimeout time.Duration
WriteTimeout time.Duration
IdleTimeout time.Duration
}
// InitConfig 初始化配置
func InitConfig() *Config {
return &Config{
Port: utils.GetEnv("PORT", "8080"),
Mode: utils.GetEnv("GIN_MODE", "debug"),
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 60 * time.Second,
}
}
+8
View File
@@ -0,0 +1,8 @@
package model
// Response 统一响应结构
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
+8
View File
@@ -0,0 +1,8 @@
package model
// User 示例用户结构
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
+29
View File
@@ -0,0 +1,29 @@
package router
import (
"github.com/gin-gonic/gin"
"rear/internal/handler"
)
// 设置路由
func SetupRoutes(r *gin.Engine) {
// 默认访问
r.GET("/", handler.BasicResponse)
// 健康检查
r.GET("/health", handler.HealthCheck)
// API版本组
v1 := r.Group("/api/v1")
{
// 用户相关路由
users := v1.Group("/users")
{
users.GET("", handler.GetUsers)
users.GET("/:id", handler.GetUserByID)
users.POST("", handler.CreateUser)
users.PUT("/:id", handler.UpdateUser)
users.DELETE("/:id", handler.DeleteUser)
}
}
}
+76
View File
@@ -0,0 +1,76 @@
package service
import (
"fmt"
"go.uber.org/zap"
"net/http"
"rear/internal/model"
"rear/pkg/logger"
"time"
"github.com/gin-gonic/gin"
)
// LoggerMiddleware 日志中间件
func LoggerMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
path := c.Request.URL.Path
raw := c.Request.URL.RawQuery
// 处理请求
c.Next()
// 记录请求日志
latency := time.Since(start)
clientIP := c.ClientIP()
method := c.Request.Method
statusCode := c.Writer.Status()
if raw != "" {
path = path + "?" + raw
}
// 使用你的日志封装
logger.Info("HTTP Request",
zap.String("method", method),
zap.String("path", path),
zap.Int("status", statusCode),
zap.String("ip", clientIP),
zap.Duration("latency", latency),
zap.String("user_agent", c.Request.UserAgent()),
)
}
}
// ErrorHandlerMiddleware 错误处理中间件
func ErrorHandlerMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
if len(c.Errors) > 0 {
err := c.Errors.Last()
// 使用格式化日志
logger.Errorf("Request error: %v", err.Err)
c.JSON(http.StatusInternalServerError, model.Response{
Code: http.StatusInternalServerError,
Message: "Internal server error",
})
}
}
}
// RequestIDMiddleware 请求ID中间件
func RequestIDMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = fmt.Sprintf("%d", time.Now().UnixNano())
}
c.Header("X-Request-ID", requestID)
c.Set("request_id", requestID)
c.Next()
}
}
+11
View File
@@ -0,0 +1,11 @@
package utils
import "os"
// GetEnv 获取环境变量
func GetEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}