今天才知道RESTful這個詞,感受好落後呀。自從5月份後不多學習新知識,這是個很差的信號。html
RESTful是Representational State Transfer的縮寫。怎麼理解Representational State Transfer呢?git
所謂資源,就是一個網絡實體,或者說就是網絡上的一個具體信息。它能夠是一段音樂,一個圖片,一首歌曲,一種服務,總之就是一個具體的存在。你可使用URI(統一資源定位符)指向他們,每種資源都有一個特定的URI。要獲取這個資源,只需訪問這個URI就能夠了。所以這個URI就成爲一個獨一無二的識別符。github
資源是一個信息實體,它能夠有多種表現實體。咱們把資源的具體呈現形式,稱爲表現層(Representation),例如:圖片,txt, json等json
URI只表明資源的實體,不表明它的形式。嚴格地說,有些網址最後的".html"後綴名是沒必要要的,由於這個後綴名錶示格式,屬於"表現層"範疇,而URI應該只表明"資源"的位置。它的具體表現形式,應該在HTTP請求的頭信息中用Accept和Content-Type字段指定,這兩個字段纔是對"表現層"的描述。api
訪問一個網站,就表明了客戶端和服務器的一個互動過程。在這個過程當中,勢必涉及到數據和狀態的變化。服務器
互聯網通訊協議HTTP協議,是一個無狀態協議。這意味着,全部的狀態都保存在服務器端。所以,若是客戶端想要操做服務器,必須經過某種手段,讓服務器端發生"狀態轉化"(State Transfer)。而這種轉化是創建在表現層之上的,因此就是"表現層狀態轉化"。restful
客戶端用到的手段,只能是HTTP協議。具體來講,就是HTTP協議裏面,四個表示操做方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操做:GET用來獲取資源,POST用來新建資源(也能夠用於更新資源),PUT用來更新資源,DELETE用來刪除資源網絡
以上引用:阮一峯 理解restful架構架構
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ide
通過3天研究發現restful頗有意思,同時,我基本上填坑的,我是用go + PostgreSQL 語言寫的,go我不是太會,PostgreSQL我歷來沒用過。原本是個很簡單的玩意,硬是花了3天。go真心很差調試。
go RESTful 庫:https://github.com/ant0ine/go-json-rest
go postgreSql driver: https://github.com/go-pg/pg
主要參考的就是這個例子:
1 package main 2 3 import ( 4 "fmt" 5 "github.com/ant0ine/go-json-rest/rest" 6 "log" 7 "net/http" 8 "sync" 9 ) 10 11 func main() { 12 13 users := Users{ 14 Store: map[string]*User{}, 15 } 16 17 api := rest.NewApi() 18 api.Use(rest.DefaultDevStack...) 19 router, err := rest.MakeRouter( 20 rest.Get("/users", users.GetAllUsers), 21 rest.Post("/users", users.PostUser), 22 rest.Get("/users/:id", users.GetUser), 23 rest.Put("/users/:id", users.PutUser), 24 rest.Delete("/users/:id", users.DeleteUser), 25 ) 26 if err != nil { 27 log.Fatal(err) 28 } 29 api.SetApp(router) 30 log.Fatal(http.ListenAndServe(":8080", api.MakeHandler())) 31 } 32 33 type User struct { 34 Id string 35 Name string 36 } 37 38 type Users struct { 39 sync.RWMutex 40 Store map[string]*User 41 } 42 43 func (u *Users) GetAllUsers(w rest.ResponseWriter, r *rest.Request) { 44 u.RLock() 45 users := make([]User, len(u.Store)) 46 i := 0 47 for _, user := range u.Store { 48 users[i] = *user 49 i++ 50 } 51 u.RUnlock() 52 w.WriteJson(&users) 53 } 54 55 func (u *Users) GetUser(w rest.ResponseWriter, r *rest.Request) { 56 id := r.PathParam("id") 57 u.RLock() 58 var user *User 59 if u.Store[id] != nil { 60 user = &User{} 61 *user = *u.Store[id] 62 } 63 u.RUnlock() 64 if user == nil { 65 rest.NotFound(w, r) 66 return 67 } 68 w.WriteJson(user) 69 } 70 71 func (u *Users) PostUser(w rest.ResponseWriter, r *rest.Request) { 72 user := User{} 73 err := r.DecodeJsonPayload(&user) 74 if err != nil { 75 rest.Error(w, err.Error(), http.StatusInternalServerError) 76 return 77 } 78 u.Lock() 79 id := fmt.Sprintf("%d", len(u.Store)) // stupid 80 user.Id = id 81 u.Store[id] = &user 82 u.Unlock() 83 w.WriteJson(&user) 84 } 85 86 func (u *Users) PutUser(w rest.ResponseWriter, r *rest.Request) { 87 id := r.PathParam("id") 88 u.Lock() 89 if u.Store[id] == nil { 90 rest.NotFound(w, r) 91 u.Unlock() 92 return 93 } 94 user := User{} 95 err := r.DecodeJsonPayload(&user) 96 if err != nil { 97 rest.Error(w, err.Error(), http.StatusInternalServerError) 98 u.Unlock() 99 return 100 } 101 user.Id = id 102 u.Store[id] = &user 103 u.Unlock() 104 w.WriteJson(&user) 105 } 106 107 func (u *Users) DeleteUser(w rest.ResponseWriter, r *rest.Request) { 108 id := r.PathParam("id") 109 u.Lock() 110 delete(u.Store, id) 111 u.Unlock() 112 w.WriteHeader(http.StatusOK) 113 }
這裏有個巨坑,找了很久才發現:
1 type User struct { 2 Id string 3 Name string 4 }
這些變量必須大寫,若是小寫的,程序不會報錯,可是沒有結果。(我對json不太會,估計是這個問題)
還有就是go 封裝的PostgreSQL driver,我已無力吐槽,API明顯不給力,寫的SQL各類出錯,可是不知道錯誤緣由,硬是各類看SQL怎麼錯了。