HTTP方法 #

一、HTTP方法概述 #

1.1 常用HTTP方法 #

方法 用途 是否幂等
GET 获取资源
POST 创建资源
PUT 更新资源(完整)
PATCH 更新资源(部分)
DELETE 删除资源
HEAD 获取响应头
OPTIONS 获取支持的方法

1.2 RESTful设计原则 #

text
GET    /users      → 获取用户列表
GET    /users/:id  → 获取单个用户
POST   /users      → 创建用户
PUT    /users/:id  → 更新用户(完整)
PATCH  /users/:id  → 更新用户(部分)
DELETE /users/:id  → 删除用户

二、GET请求 #

2.1 基本GET请求 #

go
app.Get("/users", func(c *fiber.Ctx) error {
    return c.JSON(fiber.Map{
        "users": []string{"Alice", "Bob", "Charlie"},
    })
})

2.2 带参数的GET请求 #

go
// 路径参数
app.Get("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    return c.JSON(fiber.Map{
        "id": id,
    })
})

// 查询参数
app.Get("/search", func(c *fiber.Ctx) error {
    q := c.Query("q")
    page := c.Query("page", "1")
    return c.JSON(fiber.Map{
        "query": q,
        "page":  page,
    })
})

2.3 获取列表 #

go
type User struct {
    ID   string `json:"id"`
    Name string `json:"name"`
}

var users = []User{
    {ID: "1", Name: "Alice"},
    {ID: "2", Name: "Bob"},
    {ID: "3", Name: "Charlie"},
}

app.Get("/users", func(c *fiber.Ctx) error {
    // 分页参数
    page := c.QueryInt("page", 1)
    limit := c.QueryInt("limit", 10)
    
    // 计算偏移量
    offset := (page - 1) * limit
    end := offset + limit
    if end > len(users) {
        end = len(users)
    }
    
    return c.JSON(fiber.Map{
        "data":  users[offset:end],
        "page":  page,
        "limit": limit,
        "total": len(users),
    })
})

三、POST请求 #

3.1 基本POST请求 #

go
app.Post("/users", func(c *fiber.Ctx) error {
    return c.JSON(fiber.Map{
        "message": "User created",
    })
})

3.2 创建资源 #

go
type CreateUserRequest struct {
    Name  string `json:"name" validate:"required"`
    Email string `json:"email" validate:"required,email"`
    Age   int    `json:"age" validate:"min=0,max=150"`
}

var users = []User{}
var nextID = 1

app.Post("/users", func(c *fiber.Ctx) error {
    var req CreateUserRequest
    if err := c.BodyParser(&req); err != nil {
        return c.Status(400).JSON(fiber.Map{
            "error": "Invalid request body",
        })
    }
    
    // 创建用户
    user := User{
        ID:    strconv.Itoa(nextID),
        Name:  req.Name,
        Email: req.Email,
        Age:   req.Age,
    }
    nextID++
    users = append(users, user)
    
    return c.Status(201).JSON(user)
})

3.3 表单提交 #

go
app.Post("/login", func(c *fiber.Ctx) error {
    username := c.FormValue("username")
    password := c.FormValue("password")
    
    if username == "" || password == "" {
        return c.Status(400).JSON(fiber.Map{
            "error": "Username and password required",
        })
    }
    
    // 验证逻辑...
    
    return c.JSON(fiber.Map{
        "message": "Login successful",
        "token":   "jwt-token-here",
    })
})

3.4 文件上传 #

go
app.Post("/upload", func(c *fiber.Ctx) error {
    file, err := c.FormFile("file")
    if err != nil {
        return c.Status(400).JSON(fiber.Map{
            "error": "File is required",
        })
    }
    
    // 保存文件
    filename := "./uploads/" + file.Filename
    if err := c.SaveFile(file, filename); err != nil {
        return c.Status(500).JSON(fiber.Map{
            "error": "Failed to save file",
        })
    }
    
    return c.JSON(fiber.Map{
        "message":  "File uploaded",
        "filename": file.Filename,
        "size":     file.Size,
    })
})

四、PUT请求 #

4.1 基本PUT请求 #

go
app.Put("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    return c.JSON(fiber.Map{
        "message": "User updated",
        "id":      id,
    })
})

4.2 完整更新 #

go
type UpdateUserRequest struct {
    Name  string `json:"name" validate:"required"`
    Email string `json:"email" validate:"required,email"`
    Age   int    `json:"age" validate:"min=0,max=150"`
}

app.Put("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    
    var req UpdateUserRequest
    if err := c.BodyParser(&req); err != nil {
        return c.Status(400).JSON(fiber.Map{
            "error": "Invalid request body",
        })
    }
    
    // 查找用户
    for i, user := range users {
        if user.ID == id {
            // 完整更新
            users[i] = User{
                ID:    id,
                Name:  req.Name,
                Email: req.Email,
                Age:   req.Age,
            }
            return c.JSON(users[i])
        }
    }
    
    return c.Status(404).JSON(fiber.Map{
        "error": "User not found",
    })
})

五、PATCH请求 #

5.1 基本PATCH请求 #

go
app.Patch("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    return c.JSON(fiber.Map{
        "message": "User partially updated",
        "id":      id,
    })
})

5.2 部分更新 #

go
type PatchUserRequest struct {
    Name  *string `json:"name,omitempty"`
    Email *string `json:"email,omitempty"`
    Age   *int    `json:"age,omitempty"`
}

app.Patch("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    
    var req PatchUserRequest
    if err := c.BodyParser(&req); err != nil {
        return c.Status(400).JSON(fiber.Map{
            "error": "Invalid request body",
        })
    }
    
    // 查找用户
    for i, user := range users {
        if user.ID == id {
            // 部分更新(只更新提供的字段)
            if req.Name != nil {
                users[i].Name = *req.Name
            }
            if req.Email != nil {
                users[i].Email = *req.Email
            }
            if req.Age != nil {
                users[i].Age = *req.Age
            }
            return c.JSON(users[i])
        }
    }
    
    return c.Status(404).JSON(fiber.Map{
        "error": "User not found",
    })
})

六、DELETE请求 #

6.1 基本DELETE请求 #

go
app.Delete("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    return c.JSON(fiber.Map{
        "message": "User deleted",
        "id":      id,
    })
})

6.2 删除资源 #

go
app.Delete("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    
    // 查找并删除用户
    for i, user := range users {
        if user.ID == id {
            users = append(users[:i], users[i+1:]...)
            return c.JSON(fiber.Map{
                "message": "User deleted",
                "id":      id,
            })
        }
    }
    
    return c.Status(404).JSON(fiber.Map{
        "error": "User not found",
    })
})

6.3 软删除 #

go
type User struct {
    ID        string    `json:"id"`
    Name      string    `json:"name"`
    Email     string    `json:"email"`
    DeletedAt time.Time `json:"deleted_at,omitempty"`
}

app.Delete("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    
    for i, user := range users {
        if user.ID == id {
            // 软删除
            now := time.Now()
            users[i].DeletedAt = now
            return c.JSON(fiber.Map{
                "message": "User soft deleted",
                "id":      id,
            })
        }
    }
    
    return c.Status(404).JSON(fiber.Map{
        "error": "User not found",
    })
})

七、HEAD请求 #

7.1 基本HEAD请求 #

go
app.Head("/users", func(c *fiber.Ctx) error {
    c.Set("X-Total-Count", strconv.Itoa(len(users)))
    return c.SendStatus(200)
})

7.2 检查资源存在 #

go
app.Head("/users/:id", func(c *fiber.Ctx) error {
    id := c.Params("id")
    
    for _, user := range users {
        if user.ID == id {
            c.Set("Content-Length", "0")
            return c.SendStatus(200)
        }
    }
    
    return c.SendStatus(404)
})

八、OPTIONS请求 #

8.1 基本OPTIONS请求 #

go
app.Options("/users", func(c *fiber.Ctx) error {
    c.Set("Allow", "GET, POST, PUT, DELETE, OPTIONS")
    return c.SendStatus(204)
})

8.2 CORS预检 #

go
app.Options("/*", func(c *fiber.Ctx) error {
    c.Set("Access-Control-Allow-Origin", "*")
    c.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
    c.Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
    c.Set("Access-Control-Max-Age", "86400")
    return c.SendStatus(204)
})

九、匹配所有方法 #

9.1 All方法 #

go
app.All("/api/*", func(c *fiber.Ctx) error {
    return c.JSON(fiber.Map{
        "method": c.Method(),
        "path":   c.Path(),
    })
})

9.2 Use方法 #

go
// Use方法作为中间件,匹配所有方法
app.Use("/api", func(c *fiber.Ctx) error {
    c.Set("X-Request-Time", time.Now().Format(time.RFC3339))
    return c.Next()
})

十、方法判断 #

10.1 获取请求方法 #

go
app.All("/method", func(c *fiber.Ctx) error {
    method := c.Method()
    
    return c.JSON(fiber.Map{
        "method": method,
    })
})

10.2 判断请求方法 #

go
app.All("/check", func(c *fiber.Ctx) error {
    switch c.Method() {
    case fiber.MethodGet:
        return c.SendString("GET request")
    case fiber.MethodPost:
        return c.SendString("POST request")
    case fiber.MethodPut:
        return c.SendString("PUT request")
    case fiber.MethodDelete:
        return c.SendString("DELETE request")
    default:
        return c.Status(405).SendString("Method not allowed")
    }
})

十一、RESTful API完整示例 #

11.1 完整CRUD API #

go
package main

import (
    "strconv"
    "github.com/gofiber/fiber/v2"
)

type User struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

var users = []User{
    {ID: "1", Name: "Alice", Email: "alice@example.com"},
    {ID: "2", Name: "Bob", Email: "bob@example.com"},
}

var nextID = 3

func main() {
    app := fiber.New()
    
    // 获取用户列表
    app.Get("/users", func(c *fiber.Ctx) error {
        return c.JSON(users)
    })
    
    // 获取单个用户
    app.Get("/users/:id", func(c *fiber.Ctx) error {
        id := c.Params("id")
        for _, user := range users {
            if user.ID == id {
                return c.JSON(user)
            }
        }
        return c.Status(404).JSON(fiber.Map{
            "error": "User not found",
        })
    })
    
    // 创建用户
    app.Post("/users", func(c *fiber.Ctx) error {
        var user User
        if err := c.BodyParser(&user); err != nil {
            return c.Status(400).JSON(fiber.Map{
                "error": "Invalid request body",
            })
        }
        user.ID = strconv.Itoa(nextID)
        nextID++
        users = append(users, user)
        return c.Status(201).JSON(user)
    })
    
    // 更新用户(完整)
    app.Put("/users/:id", func(c *fiber.Ctx) error {
        id := c.Params("id")
        var user User
        if err := c.BodyParser(&user); err != nil {
            return c.Status(400).JSON(fiber.Map{
                "error": "Invalid request body",
            })
        }
        for i, u := range users {
            if u.ID == id {
                user.ID = id
                users[i] = user
                return c.JSON(user)
            }
        }
        return c.Status(404).JSON(fiber.Map{
            "error": "User not found",
        })
    })
    
    // 更新用户(部分)
    app.Patch("/users/:id", func(c *fiber.Ctx) error {
        id := c.Params("id")
        var updates map[string]interface{}
        if err := c.BodyParser(&updates); err != nil {
            return c.Status(400).JSON(fiber.Map{
                "error": "Invalid request body",
            })
        }
        for i, user := range users {
            if user.ID == id {
                if name, ok := updates["name"].(string); ok {
                    users[i].Name = name
                }
                if email, ok := updates["email"].(string); ok {
                    users[i].Email = email
                }
                return c.JSON(users[i])
            }
        }
        return c.Status(404).JSON(fiber.Map{
            "error": "User not found",
        })
    })
    
    // 删除用户
    app.Delete("/users/:id", func(c *fiber.Ctx) error {
        id := c.Params("id")
        for i, user := range users {
            if user.ID == id {
                users = append(users[:i], users[i+1:]...)
                return c.SendStatus(204)
            }
        }
        return c.Status(404).JSON(fiber.Map{
            "error": "User not found",
        })
    })
    
    // OPTIONS
    app.Options("/users", func(c *fiber.Ctx) error {
        c.Set("Allow", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
        return c.SendStatus(204)
    })
    
    app.Listen(":3000")
}

十二、总结 #

12.1 HTTP方法对照表 #

方法 路由定义 用途
GET app.Get() 获取资源
POST app.Post() 创建资源
PUT app.Put() 完整更新
PATCH app.Patch() 部分更新
DELETE app.Delete() 删除资源
HEAD app.Head() 获取响应头
OPTIONS app.Options() 获取支持的方法
ALL app.All() 匹配所有方法

12.2 下一步 #

现在你已经掌握了HTTP方法,接下来让我们学习 中间件概念,了解Fiber强大的中间件系统!

最后更新:2026-03-28