Go语言通过net/http包可快速构建HTTP服务,核心步骤为:定义处理器函数处理请求、使用http.HandleFunc注册路由、调用http.ListenAndServe启动服务。处理器通过检查r.Method区分GET、POST等请求方法,利用r.URL.Query()获取查询参数,读取r.Body获取请求体。可通过实现http.Handler接口的ServeHTTP方法创建带状态的自定义处理器,便于复用和模块化。错误处理需返回恰当状态码,如http.Error(w, msg, code)或手动设置WriteHeader,确保API健壮性。

在Go语言里构建一个HTTP服务,说实话,比我想象中要直接得多。你不需要引入什么复杂的框架,标准库的
net/http
要用
net/http
http.ResponseWriter
*http.Request
http.HandleFunc
http.ListenAndServe
来看个最简单的例子:
package main
import (
"fmt"
"log"
"net/http"
)
// homeHandler 是一个简单的HTTP处理器函数
func homeHandler(w http.ResponseWriter, r *http.Request) {
// 检查请求路径,确保只响应根路径
if r.URL.Path != "/" {
http.NotFound(w, r) // 返回404
return
}
fmt.Fprintf(w, "Hello, Go HTTP!") // 向客户端写入响应
}
func main() {
// 注册处理器函数,将根路径"/"的请求交给homeHandler处理
http.HandleFunc("/", homeHandler)
// 启动HTTP服务器,监听8080端口
// ListenAndServe会阻塞,直到服务器停止或出错
log.Println("Server starting on :8080")
err := http.ListenAndServe(":8080", nil) // nil表示使用默认的多路复用器DefaultServeMux
if err != nil {
log.Fatalf("Server failed to start: %v", err)
}
}这段代码跑起来,访问
http://localhost:8080
http.ListenAndServe
http.Handler
nil
http.DefaultServeMux
http.HandleFunc
立即学习“go语言免费学习笔记(深入)”;
当你构建一个API或者一个复杂的Web应用时,仅仅响应一个固定路径是不够的。HTTP请求有不同的方法(GET、POST、PUT、DELETE等),还有各种参数(查询参数、请求体、Header)。在Go的
net/http
*http.Request
要区分请求方法,最直接的方式就是检查
r.Method
package main
import (
"fmt"
"io/ioutil" // 用于读取请求体
"log"
"net/http"
)
// userHandler 处理 /user 路径的请求
func userHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
// 处理GET请求,通常用于获取资源
userID := r.URL.Query().Get("id") // 获取查询参数,例如 /user?id=123
if userID == "" {
http.Error(w, "User ID is required", http.StatusBadRequest)
return
}
fmt.Fprintf(w, "Fetching user with ID: %s", userID)
case "POST":
// 处理POST请求,通常用于创建资源
// 读取请求体,例如JSON数据
body, err := ioutil.ReadAll(r.Body) // 注意:生产环境应限制body大小
if err != nil {
http.Error(w, "Failed to read request body", http.StatusInternalServerError)
return
}
defer r.Body.Close() // 养成关闭Body的习惯
// 假设请求体是简单的文本
fmt.Fprintf(w, "Creating user with data: %s", string(body))
default:
// 不支持的方法
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
func main() {
http.HandleFunc("/user", userHandler)
log.Println("Server starting on :8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatalf("Server failed to start: %v", err)
}
}这里我稍微展开了一下,
r.URL.Query().Get("id")r.Body
r.Body
io.Reader
switch r.Method
http.HandleFunc
http.Handler
ServeHTTP(w http.ResponseWriter, r *http.Request)
这意味着什么呢?你可以定义自己的结构体,让它拥有一些状态(比如数据库连接、配置信息),然后让这个结构体实现
ServeHTTP
举个例子:
package main
import (
"fmt"
"log"
"net/http"
)
// MyCustomHandler 结构体,可以携带一些配置信息
type MyCustomHandler struct {
Greeting string
}
// ServeHTTP 实现http.Handler接口
func (h *MyCustomHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%s, from a custom handler!", h.Greeting)
}
func main() {
// 创建一个自定义处理器的实例,并传入问候语
customHandler := &MyCustomHandler{Greeting: "Hello Go"}
// 使用http.Handle注册,而不是http.HandleFunc
// http.Handle接收一个http.Handler接口的实例
http.Handle("/custom", customHandler)
log.Println("Server starting on :8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatalf("Server failed to start: %v", err)
}
}通过
http.Handle
http.HandleFunc
http.Handler
在实际项目中,没有哪个服务能保证永远不犯错。所以,如何优雅地处理错误,并返回给客户端明确的状态码,是构建健壮HTTP服务不可或缺的一环。Go的
net/http
当你的处理器逻辑出错时,你不应该仅仅打印一个日志就完事,更重要的是要告诉客户端发生了什么。
http.ResponseWriter
WriteHeader(statusCode int)
Error(w http.ResponseWriter, error string, code int)
比如,当用户请求的资源不存在时:
package main
import (
"fmt"
"log"
"net/http"
)
// resourceHandler 处理资源请求
func resourceHandler(w http.ResponseWriter, r *http.Request) {
resourceID := r.URL.Query().Get("id")
if resourceID == "" {
// 参数缺失,返回400 Bad Request
http.Error(w, "Resource ID is required", http.StatusBadRequest)
return
}
// 模拟资源查找
if resourceID == "nonexistent" {
// 资源不存在,返回404 Not Found
http.Error(w, "Resource not found", http.StatusNotFound)
return
}
// 模拟内部服务器错误
if resourceID == "error" {
// 内部错误,返回500 Internal Server Error
log.Printf("Internal error processing resource ID %s", resourceID) // 记录日志
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "Successfully retrieved resource: %s", resourceID)
}
func main() {
http.HandleFunc("/resource", resourceHandler)
log.Println("Server starting on :8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatalf("Server failed to start: %v", err)
}
}我发现很多新手,包括我自己刚开始的时候,都容易忽略错误处理和状态码的设置。但这是衡量一个API是否专业的关键点。
http.Error
Content-Type
text/plain
w.WriteHeader()
fmt.Fprint()
另一个需要考虑的是,如果服务器启动失败怎么办?
http.ListenAndServe
error
log.Fatalf
以上就是Golang构建HTTP服务步骤 net/http包基础用法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号