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