Gorilla/Mux配置任意深度Path parameters路由方案
正在开发一款可读取JSON文件内容返回JSON响应的API,使用的测试数据文件data.json结构如下:
{ "data_1" : { "depth2" : { "depth3" : "Value of data 1" } }, "data_2" : { "depth2" : { "depth3" : "Value of data 2" } }, "data_3" : { "depth2" : { "depth3" : "Value of data 3" } } }
需要实现动态嵌套路由系统:例如客户端发起/api/data_1/depth2请求时,接口返回对应层级的JSON内容:
{ "depth3" : "Value of data 1" }
请求路径深度不固定,可根据data.json的结构无限延伸,支持/api/data_1/depth2、/api/data_1/depth2/depth3甚至/api/data_1/depth2/depth3/depth4等任意深度路径,无法使用/api/{var_1}/{var_2}这类固定层数的路由定义。
项目使用Gorilla/mux作为路由框架,当前server.go代码如下:
package main import ( .... .... ) func main() { // 项目中使用Gorilla/mux router := mux.NewRouter() // 处理请求 router.HandleFunc("/api/what_should_I_write_here?", ApiHandler) // 启动服务 log.Fatal(http.ListenAndServe(":8080", router)) }
目前已经实现NestedLookUp(data map[string]interface{}, key[]string)函数,可在ApiHandler中调用,传入形如["data_1", "depth2" ...]的键切片即可从嵌套map[string]interface{}中取出对应层级的数据,仅需要解决router的正确路由匹配规则配置问题。
Gorilla/mux支持给路径参数指定自定义正则匹配规则,直接使用通配路径规则/api/{rest:.*}即可匹配所有/api/前缀下的任意深度路径,该规则会把/api/之后的完整路径(包含多层斜杠)全部捕获到名为rest的路径参数中,不需要提前固定路由层数。
修改后的路由配置代码如下:
func main() { router := mux.NewRouter() // 匹配/api/开头的任意深度路径 router.HandleFunc("/api/{rest:.*}", ApiHandler) log.Fatal(http.ListenAndServe(":8080", router)) }
在ApiHandler中按以下逻辑处理即可:
- 调用
mux.Vars(r)取出路径参数中捕获的rest值 - 用
/作为分隔符切分字符串,过滤空值后得到需要传入NestedLookUp的键切片 - 调用已实现的嵌套查询方法拿到对应层级数据,返回JSON响应
Handler中取路径参数、生成键切片的示例代码:
import ( "net/http" "strings" "github.com/gorilla/mux" ) func ApiHandler(w http.ResponseWriter, r *http.Request) { // 取出捕获的完整后续路径 pathSeg := mux.Vars(r)["rest"] // 切分路径得到键切片 var keys []string for _, k := range strings.Split(pathSeg, "/") { if k != "" { keys = append(keys, k) } } // 后续加载data.json对应的map数据,调用NestedLookUp查询、返回响应即可 // res := NestedLookUp(loadedJsonData, keys) }
如果需要单独处理
/api(无后续路径段)的请求,额外新增一条router.HandleFunc("/api", ApiRootHandler)路由即可,上述通配规则不会匹配不带尾斜杠的/api路径。
内容的提问来源于stack exchange,提问作者Hard Code Programmer

