REST全称Representational State Transfer,是一种设计理念,用于设计那些通过标准的几个动作来操纵资源,并以此来进行相互交流的程序。
---Goweb Programming 郑兆雄著(黄健宏译)
通俗一点,就是前后端交互的一种标准。甚至更随性和放肆一些,可以理解为一种代码风格。它是Fielding大佬,在2000年博士论文中提出来的,一直是较为主流的前后端交互的一种方案,支持JSON和XML格式。个人感觉,基于JSON的标准,要比SOAP中基于XML的标准,让人感到非常舒适。
本小节内容,全部来自作者博客首页的Life Story。先上一张头像照片:
Roy T.Fielding的身世比较奇特,在新西兰怀孕,出生于加利福尼亚 (不知道他为什么要介绍自己是在哪里被怀孕的,哈哈!),父亲是UCI(加州大学尔湾分校)大学教授。fielding出生于1965年,这一年恰巧UCI建校,有三年时间在瑞德学院读物理和国际政治学。1995年夏天,成为了MIT/LCS的客座教授,是W3C的设计的主要成员,也是Apache的主要设计者。
详情请见作者博客首页。
REST是一种前后端交互的方案,在使用HTTP协议实现REST服务时(比如GET,POST,PUT等方法),URL将用于表示资源,HTTP方法则用于解析得到符合规范的json响应。由于它的巨大影响,便衍生出了Restful这样一个形容词。
REST的方便之处就在于屏蔽了后端内部的结构,前端想要什么数据,我全部以JSON格式发送给你,你拿到数据后,爱怎么渲染怎么渲染,都不关我的事了,也就是我们常说的前后端分离。
Restful风格只是一种编程规范,并不是严格的标准。设计内容包括资源设计、动作设计、返回规则设计、状态码设计等。
资源设计
在URL中携带参数的经典资源请求方式存在很大弊端。设计URL时会有大量的接口方法,URL地址设计很复杂,并且要在URL中显式的表示出资源和操作。
Restful风格的API中,每个网址代表一种资源,所以网址中只能有名词形式,不能有动词。一般来说,名词往往与数据库表格名对应。
动作设计
Restful风格的API中,支持GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS等动作。
- GET(SELECT):从服务器取资源
- POST(CREATE):从服务器新建资源
- PUT(UPDATE):在服务器更新资源,PUT会更新整个对象
- PATCH(UPDATE):在服务器更新资源,PATCH更新个别属性
- DELETE(DELETE):从服务器删除资源
- HEAD:获取一个资源的元数据,比如某个资源的hash值或最后修改日期
- OPTIONS:获得客户端针对一个资源能够实施的操作
返回规则设计
Restful风格的API中,对返回数据进行了约束。
- GET/zoos:返回资源对象的集合
- GET/zoos/1:返回单个资源对象
- POST/collection:返回新生成的资源对象
- PUT/collection/resource:返回完整的资源对象
- PATCH/collection/resource:返回完整的资源对象
- DELETE/collection/resource:返回一个空文档
状态码设计
Restful风格的API中,状态码的设计和http状态码的设计保持一致。
很多现代化Web应用程序,已经超越了简单的请求–响应模型,并以多种不同的形式,不断演进,比如SPA(Single Page Application)和移动应用,能够在获取Web服务的同时,快速的与用户进行交互。目前流行的VUE,就是在其中非常活跃的一个前端架构,基于MVVMM的模式。
Golang中httprouter
很好的支持编写REST风格的后端代码,更高层次的封装-----Gin
框架(一种轻量级GoWeb后端框架)也很好的支持编写REST风格的后端代码。
GoWeb中经典的模板加载方案,要求如下,我收到了前端发送来的请求,我需要决定把哪个html页面发送给你,并附上这个html所需要的数据,这就要求后端要多多少少控制前端的内容和参数。
package controller
import (
"html/template"
"net/http"
)
func SecretCheckHandler(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.ParseFiles("view/pages/index.html"))
t.Execute(w,nil)
}
此接口非彼接口!相比Go中的interface,这里说的接口更符合我们生活中的认知。它指的是服务器向客户端暴露哪些数据(也就是JSON数据),我们通常说暴露哪些API接口!
下面的代码,使用了著名的httprouter作为路由工具,仅仅为了说明Restful编程风格。如果浏览器输入http://localhost:8080/hello/world
,或者使用Postman等工具进行测试,结果如下!
Restful只是把需要的数据,以JSON形式写到ResponseWriter
;使用模板的GoWeb,则是把模板写到ResponseWriiter
。
package main
import (
"fmt"
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprint(w,"Welcome!\n")
}
func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
fmt.Fprintf(w,"hello,%s!\n",ps.ByName("name"))
}
func main() {
router := httprouter.New()
router.GET("/",Index)
router.GET("/hello/:name",Hello)
log.Fatal(http.ListenAndServe(":8080",router))
}