Go语言网络编程:使用 net/http 构建 RESTful API

Go语言网络编程 - 使用 net/http 构建 RESTful API 的内容。本章节将带你使用标准库构建一个简单清晰、符合 REST 风格的 API 接口服务。

一、什么是 RESTful API

REST(Representational State Transfer)是一种风格,通常遵循以下规范:

动作 方法 描述
获取资源 GET /users/users/1
创建资源 POST /users
更新资源 PUT /users/1
删除资源 DELETE /users/1

二、准备数据结构和模拟数据库

go 复制代码
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "strconv"
    "strings"
    "sync"
)

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

var (
    users   = []User{}
    nextID  = 1
    userMux sync.Mutex
)

三、实现核心的 HTTP 路由处理函数

1. 获取所有用户(GET /users)

scss 复制代码
func getUsers(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    userMux.Lock()
    defer userMux.Unlock()
    json.NewEncoder(w).Encode(users)
}

2. 获取单个用户(GET /users/{id})

scss 复制代码
func getUser(w http.ResponseWriter, r *http.Request) {
    id := getIDFromPath(r.URL.Path)
    userMux.Lock()
    defer userMux.Unlock()
    for _, u := range users {
        if u.ID == id {
            json.NewEncoder(w).Encode(u)
            return
        }
    }
    http.NotFound(w, r)
}

3. 创建用户(POST /users)

scss 复制代码
func createUser(w http.ResponseWriter, r *http.Request) {
    var u User
    if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
        http.Error(w, "Invalid JSON", http.StatusBadRequest)
        return
    }
    userMux.Lock()
    u.ID = nextID
    nextID++
    users = append(users, u)
    userMux.Unlock()

    w.WriteHeader(http.StatusCreated)
    json.NewEncoder(w).Encode(u)
}

4. 更新用户(PUT /users/{id})

go 复制代码
func updateUser(w http.ResponseWriter, r *http.Request) {
    id := getIDFromPath(r.URL.Path)
    var update User
    if err := json.NewDecoder(r.Body).Decode(&update); err != nil {
        http.Error(w, "Invalid JSON", http.StatusBadRequest)
        return
    }

    userMux.Lock()
    defer userMux.Unlock()
    for i, u := range users {
        if u.ID == id {
            users[i].Name = update.Name
            json.NewEncoder(w).Encode(users[i])
            return
        }
    }
    http.NotFound(w, r)
}

5. 删除用户(DELETE /users/{id})

scss 复制代码
func deleteUser(w http.ResponseWriter, r *http.Request) {
    id := getIDFromPath(r.URL.Path)

    userMux.Lock()
    defer userMux.Unlock()
    for i, u := range users {
        if u.ID == id {
            users = append(users[:i], users[i+1:]...)
            w.WriteHeader(http.StatusNoContent)
            return
        }
    }
    http.NotFound(w, r)
}

四、辅助函数:路径中提取 ID

go 复制代码
func getIDFromPath(path string) int {
    parts := strings.Split(path, "/")
    idStr := parts[len(parts)-1]
    id, _ := strconv.Atoi(idStr)
    return id
}

五、设置路由器并启动服务

go 复制代码
func main() {
    http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
        switch r.Method {
        case http.MethodGet:
            getUsers(w, r)
        case http.MethodPost:
            createUser(w, r)
        default:
            http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
        }
    })

    http.HandleFunc("/users/", func(w http.ResponseWriter, r *http.Request) {
        switch r.Method {
        case http.MethodGet:
            getUser(w, r)
        case http.MethodPut:
            updateUser(w, r)
        case http.MethodDelete:
            deleteUser(w, r)
        default:
            http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
        }
    })

    fmt.Println("Listening on :8080...")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

六、测试示例(使用 curl 或 Postman)

bash 复制代码
# 创建用户
curl -X POST -d '{"name":"Alice"}' http://localhost:8080/users -H "Content-Type: application/json"

# 获取所有用户
curl http://localhost:8080/users

# 获取单个用户
curl http://localhost:8080/users/1

# 更新用户
curl -X PUT -d '{"name":"Bob"}' http://localhost:8080/users/1 -H "Content-Type: application/json"

# 删除用户
curl -X DELETE http://localhost:8080/users/1

七、小结

本章展示了如何使用 Go 的标准库构建一套完整的 RESTful API 服务,包括:

  • • 路由分发
  • • JSON 编解码
  • • 方法区分(GET/POST/PUT/DELETE)
  • • 并发安全的数据结构管理
  • • 简单的路径参数解析

如需更复杂的功能(如认证、中间件、自动路由注册),可引入第三方库如 GinEchoChi 等。


相关推荐
计算机程序设计小李同学16 分钟前
基于位置服务的二手图书回收平台
java·前端·vue.js·spring boot·后端
Java程序员威哥25 分钟前
SpringBoot多环境配置实战:从基础用法到源码解析与生产避坑
java·开发语言·网络·spring boot·后端·python·spring
猿小羽38 分钟前
[TEST] Spring Boot 快速入门指南 - 1769246843980
java·spring boot·后端
Anastasiozzzz1 小时前
常见限流算法--【令牌桶】【漏桶】【固定窗口】【滑动窗口】
java·redis·后端·算法·面试
历程里程碑2 小时前
Linux 4 指令结尾&&通过shell明白指令实现的原理
linux·c语言·数据结构·笔记·算法·排序算法
Zfox_2 小时前
【Docker#2】容器化虚拟化
运维·后端·docker·容器
小北方城市网2 小时前
Spring Cloud Gateway实战:路由、限流、熔断与鉴权全解析
java·spring boot·后端·spring·mybatis
tobias.b2 小时前
408真题解析-2010-11-数据结构-基础排序算法特征
数据结构·算法·排序算法·计算机考研·408真题解析
晨非辰2 小时前
Linux权限实战速成:用户切换/文件控制/安全配置15分钟掌握,解锁核心操作与权限模型内核逻辑
linux·运维·服务器·c++·人工智能·后端
Loo国昌11 小时前
【LangChain1.0】第五阶段:RAG高级篇(高级检索与优化)
人工智能·后端·语言模型·架构