asp.net 多网站,湖南长沙理工大学,中国移动生活app下载安装,网站栏目页 优化前言
在之前的文章中#xff0c;我们用Go的标准库来实现了服务器#xff0c;JSON渲染重构为辅助函数#xff0c;使特定的路由处理程序相当简洁。 我们剩下的问题是路径路由逻辑#xff0c;这是所有编写无依赖HTTP服务器的人都会遇到的问题#xff0c;除非服务器只处理一到…前言
在之前的文章中我们用Go的标准库来实现了服务器JSON渲染重构为辅助函数使特定的路由处理程序相当简洁。 我们剩下的问题是路径路由逻辑这是所有编写无依赖HTTP服务器的人都会遇到的问题除非服务器只处理一到两个路由否则组织路由器代码是冗长和困难的。
高级路由
首先的想法是抽象路由可能使用一组函数或带有方法的数据类型有许多有趣的临时方法可以做到这一点Go生态系统中有许多功能强大且使用良好的三方路由包可以为做这件事。 我们再回顾一下设计的服务器路由
POST /page/ : create a page, returns ID
GET /page/pageid : returns a single page by ID
GET /page/ : returns all pages
DELETE /page/pageid : delete a page by ID
PUT /page/pageid : update a page by ID
GET /tag/tagname : returns list of pages with this tag
GET /due/yy/mm/dd : returns list of pages due by this date我们可以做几件事来使路由更符合观感
添加一种方法来为同一路由上的不同方法设置单独的处理程序。例如/page/的POST应该转到一个处理程序GET /page/到另一个处理程序等等。添加一种“更深”匹配的方法例如我们应该可以说/page/进入一个处理程序而 /page/使用数字ID进入另一个处理程序。当我们这样做时匹配器应该只从/page/中提取数字ID并以某种方便的方式将其传递给处理程序。
由于HTTP处理程序的可组合性在Go中编写自定义路由器非常简单例如最流行的第三方方路由包之一gorilla/mux。
gorilla/mux实现的服务器
gorilla/mux是最久的流行Go HTTP路由器之一根据文档名称mux代表“HTTP请求多路复用器”与标准库中的含义相同。 因为它是一个目标明确的包所以它的使用相当简单以下是路由的定义方式
router : mux.NewRouter()
router.StrictSlash(true)
server : NewPageServer()router.HandleFunc(/page/, server.createPageHandler).Methods(POST)
router.HandleFunc(/page/, server.getAllPagesHandler).Methods(GET)
router.HandleFunc(/page/, server.deleteAllPagesHandler).Methods(DELETE)
router.HandleFunc(/page/, server.updatePageHandler).Methods(PUT)
router.HandleFunc(/page/{id:[0-9]}/, server.getPageHandler).Methods(GET)
router.HandleFunc(/page/{id:[0-9]}/, server.deletePageHandler).Methods(DELETE)
router.HandleFunc(/tag/, server.tagHandler).Methods(GET)
router.HandleFunc(/due/, server.dueHandler).Methods(GET)通过将方法调用附加到路由上我们可以轻松地将同一路径上的不同方法定向到不同的处理程序。路径中的模式匹配使用正则表达式语法让我们可以轻松地区分顶级路由定义中的/page/和/page/。
我们来看看getPageHandler
func (p *PageServer) getPageHandler(w http.ResponseWriter, r *http.Request) {log.Printf(handling get page at %s\n, r.URL.Path)// Here and elsewhere, not checking error of Atoi because the router only// matches the [0-9] regex.id, _ : strconv.Atoi(mux.Vars(r)[id])ret, err : p.store.GetPage(id)if err ! nil {http.Error(w, err.Error(), http.StatusNotFound)return}renderJSON(w, ret)
}在路由定义中路由/page/{id:[0-9]}/定义了解析路径的正则表达式但也将标识符部分分配给“id”。这个“变量”可以通过在请求上调用mux.Vars来访问。
方法对比
为了理解GET /page/路由在我们的原始服务器中是如何处理的必须采用以下代码阅读路径 而这是使用gorilla/mux时的路径 除了可以跳过的步骤更少之外要阅读的代码也大大减少了从代码可读性的角度来看使用gorilla/mux的路径定义简短明了阅读者很清楚这是如何工作的。另一个优势是我们现在可以在一个地方一目了然地轻松查看所有路由。事实上路由配置代码现在看起来与我们非正式的REST API定义非常相似。 像gorilla/mux这样的包因为它们是一个精密工具他们只做一件事而且做得很好而且他们不会“感染”整个程序使他们以后难以删除或替换。如果我们检查这部分的服务器代码我们会注意到使用gorilla/mux的部分仅限于相对较少的代码行。如果我们在项目生命周期的后期发现这个包有一个致命的限制用另一个路由包或手动版本替换它应该是相当简单的。