Go Web 编程入门:HTTP 自定义路由

简介: Go 语言提供功能丰富的 net/http,实现了基础的 HTTP 中的 client 和 server 功能。在这一篇文章也有介绍一个基础的 HelloWorld 应用。

引言

Go 语言提供功能丰富的 net/http,实现了基础的 HTTP 中的 clientserver 功能。在这一篇文章也有介绍一个基础的 HelloWorld 应用。


如果没看过,也可以使用下面的代码创建一个简易 HTTP 的 server 服务:

package main
import (
  "log"
  "net/http"
)
type Handler struct{}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  _, err := w.Write([]byte("Welcome to my Website!"))
  if err != nil {
    log.Println(err)
  }
}
func main() {
  log.Println(http.ListenAndServe("127.0.0.1:8080", &Handler{}))
}

http.ListenAndServe 的第一个参数是传入监听的地址,第二个参数是 http.Handle 接口实现者。该接口需要 ServeHTTP(w http.ResponseWriter, r *http.Request) 函数。这个函数将处理我们服务器上的所有请求。

第一个终端上使用 go run main.go 运行该服务器:

$ go run main.go 

然后打开另个一终端:

$ curl localhost:8080/
Welcome to my Website!
$ curl localhost:8080/hello
Welcome to my Website!


我们还可以配置服务器来处理特定的 URL,例如 /hello

package main
import (
  "log"
  "net/http"
)
type Handler struct{}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  _, err := w.Write([]byte("Welcome to my Website!"))
  if err != nil {
    log.Println(err)
  }
}
func main() {
  http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
    _, err := w.Write([]byte("Hello, world!"))
    if err != nil {
      log.Println(err)
    }
  })
  log.Println(http.ListenAndServe("127.0.0.1:8080", nil))
}


运行另一个终端,能看到如下结果::

$ curl localhost:8080/hello
Hello, world!
$ curl localhost:8080/
404 page not found

它是如何工作的?当我们调用 http.HandleFunc 时,路径和处理函数被添加到 net/http.DefaultServeMux 结构中,即包含所有这些。当我们调用特定的 URL 时,net/http.DefaultServeMux 用于查找特定的处理程序。如果未找到处理程序,将生成标准 404 响应。


标准路由对每个注册的 URL 实现唯一的纯 URL 比较。模式匹配,例如匹配 /hello/{page} 之类的表达式,其中页面参数在多个调用之间可能不同,这对于标准路由器是不可能的。要实现这一点,我们需要自己实现模式匹配或使用路由器库之一。


自定义路由

我们可以使用任何其他路由器,例如 gorilla/mux :一个强大的 HTTP 路由器和 URL 匹配器,用于构建 Go web 服务器 🦍。目前已经在 Github 收获 16.4 k 的 star,它支持模式匹配。

func main() {
  r := mux.NewRouter()
  r.HandleFunc("/products/{key}", ProductHandler)
  r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
  r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
  http.Handle("/", r)
}

接下来,在处理程序中,我们可以从 URL 中获取变量:

中间件

在标准 Web 服务中,不仅有处理程序的代码在每个请求上运行。还有一些通用代码执行一些通用工作——日志记录、统计信息抓取、授权检查等。这些通用代码称为中间件。

GO 标准库中没有明确的中间件实现。但是任何人都可以通过使用嵌套处理程序来实现类似的东西。让我们看一下日志中间件,它将每个请求的 URL 打印到控制台:

package main
import (
  "log"
  "net/http"
)
type LoggingMiddleware struct {
  handler http.Handler
}
func NewLoggingMiddleware(handler http.Handler) *LoggingMiddleware {
  return &LoggingMiddleware{
    handler: handler,
  }
}
func (l *LoggingMiddleware) ServeHTTP(w http.ResponseWriter, req *http.Request) {
  log.Println(req.URL, "requested")
  l.handler.ServeHTTP(w, req)
}
type Handler struct{}
func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
  _, err := w.Write([]byte("hello"))
  if err != nil {
    log.Println(err)
  }
}
func main() {
  log.Println(http.ListenAndServe(":9090", NewLoggingMiddleware(&Handler{})))
}
$ curl localhost:8080/
hello
$ curl localhost:8080/hello
hello


在对我们服务器的每个请求中,我们现在可以在控制台中看到以下数据:

$ go run main.go
2022/04/27 23:44:18 / requested
2022/04/27 23:44:23 /hello requested

很多游戏的 Go Web 库如 echogin 可以显着地帮助实现中间件。此外,许多库已经涵盖了最流行的中间件任务。


HTTP 客户端


net/http 包中有一个 Client 结构,它负责 HTTP 客户端请求:

package main
import (
  "fmt"
  "io/ioutil"
  "log"
  "net/http"
)
func main() {
  client := http.Client{}
  resp, err := client.Get("https://bing.com/")
  if err != nil {
    log.Fatal(err)
  }
  buf, err := ioutil.ReadAll(resp.Body)
  resp.Body.Close()
  if err != nil {
    log.Fatal(err)
  }
  fmt.Println(string(buf))
}


运行结果会返回该网页的内容:

image.png

相关文章
|
2月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
241 4
|
6月前
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
350 61
|
4月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
5月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
6月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
5月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
398 0
|
6月前
|
JSON 编解码 API
Go语言网络编程:使用 net/http 构建 RESTful API
本章介绍如何使用 Go 语言的 `net/http` 标准库构建 RESTful API。内容涵盖 RESTful API 的基本概念及规范,包括 GET、POST、PUT 和 DELETE 方法的实现。通过定义用户数据结构和模拟数据库,逐步实现获取用户列表、创建用户、更新用户、删除用户的 HTTP 路由处理函数。同时提供辅助函数用于路径参数解析,并展示如何设置路由器启动服务。最后通过 curl 或 Postman 测试接口功能。章节总结了路由分发、JSON 编解码、方法区分、并发安全管理和路径参数解析等关键点,为更复杂需求推荐第三方框架如 Gin、Echo 和 Chi。
|
6月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
前端开发 JavaScript 安全
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第27天】本文介绍了HTTP/2和HTTPS在前端性能调优中的应用。通过多路复用、服务器推送和头部压缩等特性,HTTP/2显著提升了Web性能。同时,HTTPS确保了数据传输的安全性。文章提供了示例代码,展示了如何使用Node.js创建一个HTTP/2服务器。
344 3
|
10月前
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
337 20