REST API 高性能路由库设计
REST API 介绍
REST API
是前后端分离最佳实践,是开发的一套标准或者说是一套规范,不是框架。
-
每一个
URL
代表一种资源; -
客户端和服务器之间,传递这种资源的某种表现层;
-
客户端通过
GET
、POST
、DELETE
、PUT
等多个HTTP
请求方法,对服务器端资源进行操作,实现"表现层状态转化"。
作业要求
由于本次作业并没有详细的作业要求,根据课程网页以及老师上课所说大致作业要求如下:设计一个专用于 REST API
高性能路由库,并且测试 github
所有的官方 API
实验环境
操作系统:Mac OS
编辑器:Visual Studio Code
go 版本:go1.15.2 darwin/amd64
设计说明
获取程序包
输入以下的命令即可获取我实现的 myRxgo
包
go get github.com/hupf3/RestAPI
或者在 src
的相应目录下输入以下命令
git clone https://github.com/hupf3/RestAPI.git
go build
go install
简单说明
该程序包实现了 http.Handler
的中间件,并且实现了以下功能:
- 路由参数
- 支持正则表达式匹配
- 根据路由生成地址
- 自定义附加匹配项
- 自动生成请求的内容
使用示例:
m := mux.New(false, false, false, nil, nil).
Get("/users/1", h).
Post("/login", h).
Get("/pages/{id:\\d+}.html", h).
Get("/posts/{path}.html", h).
Options("/users/1", "GET").
// 前缀统一
p := m.Prefix("/api")
p.Get("/logout", h)
p.Post("/login", h)
// 相同资源的不同操作
res := p.Resource("/users/{id:\\d+}")
res.Get(h)
res.Post(h)
res.URL(map[string]string{
"id": "5"})
http.ListenAndServe(":8080", m)
正则表达式的匹配:
/posts/{
id:\\d+}
/posts/{
:\\d+}
路由参数的获取可通过 Params
函数:
params := Params(r)
id, err := params.Int("id")
id := params.MustInt("id", 0)
其他的具体用法也可以查看本程序包中的 API 文档
包文件结构
首先通过 tree
命令查看包的内容如下:
根据上图分别介绍各个文件以及目录的设计含义:
-
API.html
:根据godoc
命令自动生成的API
文档 -
README.md
:说明文档 -
specification.md
:程序包设计说明文档 -
bench_test.go
:专门为功能测试写的测试文件,主要用来测试所有官方Github API
;设计了存储API
的结构体:type api struct { method string routeItem string // 路由项 test string // 测试地址 }
设计了存储全部官方
Github API
的数组:var apis = []*api{ { method: http.MethodGet, routeItem: "/events"}, { method: http.MethodGet, routeItem: "/repos/{owner}/{repo}/events"}, ... }
-
go.mod/go.sum
:设计的程序包需要依赖的库 -
help
:此目录放置了本次实验项目需要的辅助型函数-
handles
:该程序包实现的功能是处理节点下与处理函数之间的关系-
handlers.go
:设计了对应于每个请求方法的处理函数;// 对应于每个请求方法的处理函数 type Handlers struct { handlers map[string]http.Handler optionsAllow string // 报头内容 optionsState optionsState // 请求的处理方式 headState headState }
声明一个新的
Handler
;// 声明一个新的 Handler func New(disableOptions, disableHead bool) *Handlers { }
添加一个处理函数;
// 添加一个处理函数 func (hs *Handlers) Add(h http.Handler, methods ...string) error { }
判断方法是否存在;
// 方法是否存在 func methodExists(m string) bool { }
去除某个请求方法的处理函数;
// 去除某个请求方法的处理函数 func (hs *Handlers) Remove(methods ...string) bool { } </
-
-