📝 main.go - 入口文件
完整案例
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"sync"
"time"
)
// ============= 1. 结构体定义 =============
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
// ============= 2. 接口定义 =============
type UserStore interface {
Create(user *User) error
Get(id int) (*User, error)
List() ([]User, error)
Update(user *User) error
Delete(id int) error
}
// ============= 3. 接口实现(内存存储) =============
type MemoryStore struct {
mu sync.RWMutex // 读写锁
users map[int]*User // 用户数据
idSeq int // ID生成器
}
// 构造函数
func NewMemoryStore() *MemoryStore {
return &MemoryStore{
users: make(map[int]*User),
idSeq: 1,
}
}
// Create - 创建用户
func (s *MemoryStore) Create(user *User) error {
s.mu.Lock()
defer s.mu.Unlock()
user.ID = s.idSeq
user.CreatedAt = time.Now()
s.users[user.ID] = user
s.idSeq++
return nil
}
// Get - 获取单个用户
func (s *MemoryStore) Get(id int) (*User, error) {
s.mu.RLock() // 读锁
defer s.mu.RUnlock()
user, ok := s.users[id]
if !ok {
return nil, fmt.Errorf("user not found: %d", id)
}
return user, nil
}
// List - 列出所有用户
func (s *MemoryStore) List() ([]User, error) {
s.mu.RLock() // 读锁
defer s.mu.RUnlock()
users := make([]User, 0, len(s.users))
for _, user := range s.users {
users = append(users, *user)
}
return users, nil
}
// Update - 更新用户
func (s *MemoryStore) Update(user *User) error {
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.users[user.ID]; !ok {
return fmt.Errorf("user not found: %d", user.ID)
}
s.users[user.ID] = user
return nil
}
// Delete - 删除用户
func (s *MemoryStore) Delete(id int) error {
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.users[id]; !ok {
return fmt.Errorf("user not found: %d", id)
}
delete(s.users, id)
return nil
}
// ============= 4. HTTP 服务器 =============
type Server struct {
store UserStore
mux *http.ServeMux
}
// 创建服务器
func NewServer(store UserStore) *Server {
s := &Server{
store: store,
mux: http.NewServeMux(),
}
// 注册路由
s.mux.HandleFunc("/users", s.handleUsers)
s.mux.HandleFunc("/users/", s.handleUser)
return s
}
// 处理用户列表和创建
func (s *Server) handleUsers(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
s.listUsers(w, r)
case http.MethodPost:
s.createUser(w, r)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
// 列出所有用户(GET /users)
func (s *Server) listUsers(w http.ResponseWriter, r *http.Request) {
users, err := s.store.List()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(users)
}
// 创建用户(POST /users)
func (s *Server) createUser(w http.ResponseWriter, r *http.Request) {
var user User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := s.store.Create(&user); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)
}
// 处理单个用户操作
func (s *Server) handleUser(w http.ResponseWriter, r *http.Request) {
// 解析URL中的ID
idStr := r.URL.Path[len("/users/"):]
id, err := strconv.Atoi(idStr)
if err != nil {
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
}
switch r.Method {
case http.MethodGet:
s.getUser(w, r, id)
case http.MethodDelete:
s.deleteUser(w, r, id)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
// 获取用户(GET /users/:id)
func (s *Server) getUser(w http.ResponseWriter, r *http.Request, id int) {
user, err := s.store.Get(id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
// 删除用户(DELETE /users/:id)
func (s *Server) deleteUser(w http.ResponseWriter, r *http.Request, id int) {
if err := s.store.Delete(id); err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.WriteHeader(http.StatusNoContent)
}
// ============= 5. 主函数 =============
func main() {
// 创建存储实例
store := NewMemoryStore()
// 创建HTTP服务器
server := NewServer(store)
// 启动服务
addr := ":8080"
log.Printf("🚀 Server starting on %s\n", addr)
if err := http.ListenAndServe(addr, server.mux); err != nil {
log.Fatal("❌ Server failed to start:", err)
}
}