[golang] REST

61 阅读2分钟

什么是 REST(Representational State Transfer)?

  • 资源(Resources),一个 URI 表示一个资源。
  • 表现层(Representation),URI 确定一个资源,那么如何确定它的具体表现形式呢?应该在 HTTP 请求的头信息中用 AcceptContent-Type 字段指定,这两个字段才是对“表现层”的描述。
  • 状态转化(State Transfer),HTTP 协议里面,四个表示操作方式的动词:GET(获取)、POST(创建或者更新)、PUT(更新)、DELETE(删除)。 另一个重要的 REST 原则是系统分层,这表示组件无法触达除了与它直接交互的层次以外的组件。通过将系统知识限制在单个层,可以限制整个系统的复杂性,从而促进了底层的独立性。
    image.png
    image.png

go 实现 RESTful

go 没有为 REST 提供直接支持,但是因为 RESTful 是基于 HTTP 协议实现的。当然需要针对 REST 做一些改造,REST 是根据不同的 method 来处理相应的资源,目前已经存在的很多自称是 REST 的应用,其实并没有真正的实现 REST,暂且把这些应用根据实现的 method 分成几个级别。
image.png
有时候,HTTP 客户端只能发出 GET 和 POST 请求:

  • HTML 标准只能通过链接和表单支持 GET 和 POST。在没有 Ajax 支持的网页浏览器中不能发出 PUT 或 DELETE 命令。
  • 有些防火墙会挡住 HTTP 的 PUT 和 DELETE 请求,要绕过这个限制,客户端需要把实际的 PUT 和 DELETE 请求通过 POST 请求穿透过来。 现在可以通过 POST 里面增加隐藏字段 _method 来模拟 PUT、DELETE,然后服务器端需要做转换。
func main() {
    router := httprouter.New()
    router.GET("/", Index)
    router.GET("/hello/:name", Hello)

    router.GET("/user/:uid", getuser)
    router.POST("/adduser/:uid", adduser)
    router.DELETE("/deluser/:uid", deleteuser)
    router.PUT("/moduser/:uid", modifyuser)

    // http.HandleFunc("/test1", SimpleServer)
    // http.HandleFunc("/test2", FormServer)

    log.Fatal(http.ListenAndServe(":8080", router))
}

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 getuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    uid := ps.ByName("uid")
    fmt.Fprintf(w, "you are get user %s", uid)
}

func modifyuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    uid := ps.ByName("uid")
    fmt.Fprintf(w, "you are modify user %s", uid)
}

func deleteuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    uid := ps.ByName("uid")
    fmt.Fprintf(w, "you are delete user %s", uid)
}

func adduser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    // uid := r.FormValue("uid")
    uid := ps.ByName("uid")
    fmt.Fprintf(w, "you are add user %s", uid)
}