A:增加HTTP基础功能的访问和HTTP模板
This commit is contained in:
1 parent
e4de5917cd
commit
f67e27320f
11 files changed
+620
-6
No files matched your search
@@ -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",
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package model
|
||||
|
||||
// Response 统一响应结构
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package model
|
||||
|
||||
// User 示例用户结构
|
||||
type User struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in new issue
Block a user