package main import ( "context" "encoding/json" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" ) // 模型 type Task struct { ID int64 `json:"id"` Title string `json:"title"` Description string `json:"description"` Status string `json:"status"` Priority int `json:"priority"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // 响应 type Response struct { Code int `json:"code"` Message string `json:"message"` Data interface{} `json:"data,omitempty"` } // 内存存储(模拟数据库) var tasks = make(map[int64]*Task) var nextID int64 = 1 // Handler func createTask(w http.ResponseWriter, r *http.Request) { var task Task if err := json.NewDecoder(r.Body).Decode(&task); err != nil { respondError(w, http.StatusBadRequest, "invalid request body") return } if task.Title == "" { respondError(w, http.StatusBadRequest, "title is required") return } task.ID = nextID nextID++ task.Status = "todo" task.CreatedAt = time.Now() task.UpdatedAt = time.Now() tasks[task.ID] = &task respondJSON(w, http.StatusCreated, "created", task) } func getTasks(w http.ResponseWriter, r *http.Request) { taskList := make([]*Task, 0, len(tasks)) for _, t := range tasks { taskList = append(taskList, t) } respondJSON(w, http.StatusOK, "success", taskList) } func respondJSON(w http.ResponseWriter, code int, msg string, data interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) json.NewEncoder(w).Encode(Response{Code: code, Message: msg, Data: data}) } func respondError(w http.ResponseWriter, code int, msg string) { respondJSON(w, code, msg, nil) } // 中间件 func loggerMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { start := time.Now() log.Printf("Started %s %s", r.Method, r.URL.Path) next(w, r) log.Printf("Completed %s %s in %v", r.Method, r.URL.Path, time.Since(start)) } } func recoveryMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { log.Printf("Panic recovered: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } }() next(w, r) } } func main() { // 路由 http.HandleFunc("/tasks", recoveryMiddleware(loggerMiddleware(createTask))) http.HandleFunc("/tasks", recoveryMiddleware(loggerMiddleware(getTasks))) srv := &http.Server{ Addr: ":8080", Handler: nil, // 使用默认 ServeMux } // 启动服务器 go func() { log.Println("Server starting on port 8080") if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatal(err) } }() // 优雅关闭 quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { log.Fatal("Server forced to shutdown:", err) } log.Println("Server exited") }