Go标准库的net/http包提供了完整的HTTP客户端和服务器实现。
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", helloHandler)
fmt.Println("服务器启动在 http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
func userHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
fmt.Fprintf(w, "GET请求")
case http.MethodPost:
fmt.Fprintf(w, "POST请求")
case http.MethodPut:
fmt.Fprintf(w, "PUT请求")
case http.MethodDelete:
fmt.Fprintf(w, "DELETE请求")
default:
http.Error(w, "方法不允许", http.StatusMethodNotAllowed)
}
}
package main
import (
"fmt"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", homeHandler)
mux.HandleFunc("/about", aboutHandler)
mux.HandleFunc("/api/users", usersHandler)
http.ListenAndServe(":8080", mux)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "首页")
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "关于页面")
}
func usersHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "用户列表")
}
func searchHandler(w http.ResponseWriter, r *http.Request) {
// 查询参数
query := r.URL.Query()
keyword := query.Get("q")
page := query.Get("page")
fmt.Fprintf(w, "搜索: %s, 页码: %s", keyword, page)
}
// 访问: http://localhost:8080/search?q=golang&page=1
func loginHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "只支持POST", http.StatusMethodNotAllowed)
return
}
// 解析表单数据
r.ParseForm()
username := r.FormValue("username")
password := r.FormValue("password")
fmt.Fprintf(w, "用户名: %s", username)
}
package main
import (
"encoding/json"
"net/http"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func getUserHandler(w http.ResponseWriter, r *http.Request) {
user := User{
ID: 1,
Name: "Alice",
Email: "alice@example.com",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
func createUserHandler(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
}
// 处理用户创建逻辑
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)
}
中间件是处理HTTP请求的函数链,用于日志、认证、CORS等。
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("%s %s\n", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token == "" {
http.Error(w, "未授权", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/api/users", usersHandler)
// 应用中间件
handler := loggingMiddleware(authMiddleware(mux))
http.ListenAndServe(":8080", handler)
}
package main
import (
"encoding/json"
"net/http"
"strconv"
"strings"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
var users = []User{
{ID: 1, Name: "Alice"},
{ID: 2, Name: "Bob"},
}
func usersHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
// GET /api/users - 获取所有用户
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(users)
case http.MethodPost:
// POST /api/users - 创建用户
var user User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
user.ID = len(users) + 1
users = append(users, user)
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)
default:
http.Error(w, "方法不允许", http.StatusMethodNotAllowed)
}
}
func userHandler(w http.ResponseWriter, r *http.Request) {
// 提取ID: /api/users/1
parts := strings.Split(r.URL.Path, "/")
if len(parts) < 4 {
http.Error(w, "无效的URL", http.StatusBadRequest)
return
}
id, err := strconv.Atoi(parts[3])
if err != nil {
http.Error(w, "无效的ID", http.StatusBadRequest)
return
}
switch r.Method {
case http.MethodGet:
// GET /api/users/:id - 获取单个用户
for _, user := range users {
if user.ID == id {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
return
}
}
http.Error(w, "用户未找到", http.StatusNotFound)
case http.MethodPut:
// PUT /api/users/:id - 更新用户
var updatedUser User
if err := json.NewDecoder(r.Body).Decode(&updatedUser); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
for i, user := range users {
if user.ID == id {
users[i].Name = updatedUser.Name
json.NewEncoder(w).Encode(users[i])
return
}
}
http.Error(w, "用户未找到", http.StatusNotFound)
case http.MethodDelete:
// DELETE /api/users/:id - 删除用户
for i, user := range users {
if user.ID == id {
users = append(users[:i], users[i+1:]...)
w.WriteHeader(http.StatusNoContent)
return
}
}
http.Error(w, "用户未找到", http.StatusNotFound)
default:
http.Error(w, "方法不允许", http.StatusMethodNotAllowed)
}
}
func main() {
http.HandleFunc("/api/users", usersHandler)
http.HandleFunc("/api/users/", userHandler)
fmt.Println("服务器启动在 http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
Gin是一个高性能的Web框架,提供了更简洁的API和更多功能。
go get -u github.com/gin-gonic/gin
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Hello, Gin!",
})
})
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{
"user_id": id,
})
})
r.POST("/users", func(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, user)
})
r.Run(":8080")
}
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Printf("%s %s\n", c.Request.Method, c.Request.URL.Path)
c.Next()
}
}
func Auth() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.Abort()
return
}
c.Next()
}
}
func main() {
r := gin.New()
r.Use(Logger())
api := r.Group("/api")
api.Use(Auth())
{
api.GET("/users", getUsers)
api.POST("/users", createUser)
}
r.Run(":8080")
}