Golang中的Http路由规则

使用Golang创建一个Http服务是非常简单的,使用内置的net/http包即可。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
"net/http"
"time"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World."))
})

http.HandleFunc("/time", func(w http.ResponseWriter, r *http.Request) {
now := time.Now()
s := fmt.Sprintf("{\"time\": \"%s\"}", now)
w.Write([]byte(s))
})
http.ListenAndServe(":7000", nil)

}

可以看到我们访问根路径/的时候,会返回Hello World
访问/time的时候,返回:

1
2
3
{
"time": "2019-06-09 10:20:00.560492 +0800 CST m=+947.401980568"
}

那么问题来了,如果我们访问/time/xxx会返回什么?

404?

看结果:

Hello World,惊不惊喜,意不意外?

路由规则

  • URL分为两种
    • 末尾是/: 表示一个子树,后面可以跟其他子路径。
    • 末尾不是/: 表示一个叶子,是一个固定的路径。
  • 采用最长匹配原则,如果有多个匹配,一定是采用匹配路径最长的那个进行处理。
  • 如果没有找到任何的匹配项,会返回404错误。

结合路由规则可以发现:
/time/xxx 第一,没有匹配到/time/xxx的路由,但是匹配到了/,所以最终返回了Hello World
那照这意思,写了根路径的路由还就相当于消灭404了,不科学啊。

1
2
3
4

http.HandleFunc("/time", func(w http.ResponseWriter, r *http.Request) {
改成
http.HandleFunc("/time/", func(w http.ResponseWriter, r *http.Request) {

我们就可以发现/time/xxx匹配到了合法路由,返回了时间。

虽然内置的http包很方便的就能写出一个http服务,但是我们可以看到,路由用正则来匹配,还是有些怪异的地方,比如:

  • 写了根路径就等于扼杀了404
  • /time/xxx 如果xxx是一个路由上的参数,那么还需要自己来解析,获取参数,不是很方便。
  • 使用正则来匹配路,效率上是不那么高效的。
加载评论框需要科学上网