Golang简化路由处理程序实现无框架参数处理
Golang简化路由处理程序实现无框架参数处理 在 rocket.rs 中,我们有这样简单的路由代码:
#[get("/hello/<name>/<age>")]
fn hello(name: &str, age: u8) -> String {
format!("Hello, {} year old named {}!", age, name)
}
如果你在浏览器中访问 http://localhost:8000/hello/John/58,你会看到:
Hello, 58 year old named John!
我读过 这个,但被采纳的 答案 是关于为单个路由实现 Go url 参数映射 的方法,该方法可以将 http://localhost:8080/blob/123/test 解析为 /blob/{id}/test 并显示所需的路由。
我知道那里有一些很棒的路由器/框架,但我希望自己构建简单的代码,以便更好地理解 HTTP 路由处理器。
假设我有:
type Tender struct {
tenderReference string
venderCode int
}
func (t Tender) readWrite() {
fmt.Printf("Tender %s is ready for vendor %d to review and submit\n", t.tenderReference, t.venderCode)
}
func (t Tender) readOnly(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Tender %s already submitted by vender %d\n", t.tenderReference, t.venderCode)
}
并且希望我的路由类似于:
/api/tender/readWrite/{tenderReference}/vendor/{venderCode}调用func (t Tender) readWrite(){}/api/tender/readOnly/{tenderReference}/vendor/{venderCode}调用func (t Tender) readOnly(){}
我需要构建多少个路由处理器?
更多关于Golang简化路由处理程序实现无框架参数处理的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang简化路由处理程序实现无框架参数处理的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中实现无框架参数处理,你可以使用net/http的标准库配合自定义路由解析。对于你的需求,需要构建两个路由处理器,但可以通过一个通用的处理器函数来动态处理不同的路径和方法。以下是示例代码:
package main
import (
"fmt"
"net/http"
"strings"
)
type Tender struct {
tenderReference string
venderCode int
}
func (t Tender) readWrite() {
fmt.Printf("Tender %s is ready for vendor %d to review and submit\n", t.tenderReference, t.venderCode)
}
func (t Tender) readOnly(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Tender %s already submitted by vender %d\n", t.tenderReference, t.venderCode)
w.WriteHeader(http.StatusOK)
w.Write([]byte("ReadOnly processed"))
}
func parseTenderPath(path string) (tenderReference string, venderCode int, action string, ok bool) {
// 路径格式: /api/tender/{action}/{tenderReference}/vendor/{venderCode}
parts := strings.Split(path, "/")
if len(parts) != 7 {
return "", 0, "", false
}
if parts[1] != "api" || parts[2] != "tender" || parts[5] != "vendor" {
return "", 0, "", false
}
action = parts[3]
tenderReference = parts[4]
// 简单转换venderCode,实际使用时需添加错误处理
fmt.Sscanf(parts[6], "%d", &venderCode)
return tenderReference, venderCode, action, true
}
func tenderHandler(w http.ResponseWriter, r *http.Request) {
tenderRef, vendorCode, action, ok := parseTenderPath(r.URL.Path)
if !ok {
http.NotFound(w, r)
return
}
t := Tender{
tenderReference: tenderRef,
venderCode: vendorCode,
}
switch action {
case "readWrite":
t.readWrite()
w.WriteHeader(http.StatusOK)
w.Write([]byte("ReadWrite processed"))
case "readOnly":
t.readOnly(w, r)
default:
http.NotFound(w, r)
}
}
func main() {
http.HandleFunc("/api/tender/", tenderHandler)
http.ListenAndServe(":8080", nil)
}
这个实现使用单个tenderHandler处理所有以/api/tender/开头的路由。parseTenderPath函数从URL路径中提取参数,然后根据action字段调用相应的方法。访问示例:
http://localhost:8080/api/tender/readWrite/REF123/vendor/456调用readWritehttp://localhost:8080/api/tender/readOnly/REF789/vendor/101调用readOnly
如果需要更灵活的路径匹配,可以考虑使用正则表达式:
import "regexp"
var tenderPathRegex = regexp.MustCompile(`^/api/tender/(readWrite|readOnly)/([^/]+)/vendor/(\d+)$`)
func parseTenderPathRegex(path string) (tenderReference string, venderCode int, action string, ok bool) {
matches := tenderPathRegex.FindStringSubmatch(path)
if matches == nil {
return "", 0, "", false
}
action = matches[1]
tenderReference = matches[2]
fmt.Sscanf(matches[3], "%d", &venderCode)
return tenderReference, venderCode, action, true
}
这种方法避免了依赖外部框架,同时保持了代码的简洁性和可维护性。

