實作目標
寫一個簡單的Web Server,處裡不同HTTP動作的請求,並輸出字串回應。
開始
在Go的工作目錄底下,建立一個新資料夾叫 SimpleRESTAPI,並建立一個主程式的執行檔 main.go。基本的檔案內容如下,這裡需要引入net套件中的http函式庫,後續才能用Go產生一個 http server。
package main
import(
"fmt"
"net/http"
)
func main() {
}
階段一: 建立一個 web server
撰寫一個notFound的處裡器,讓 server 啟動後可以顯示一點東西。在這個notFound函式會傳入兩個參數。先從第二個參數說起 ,r 代表Request負責接收client端發出的請求,並交由第一個參數 w 負責為請求做出回應與寫入訊息。針對寫入的訊息,在函式內可以設定了http的表頭、狀態及內容。
func notFound(w http.ResponseWriter, r *http.Request){
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(`{"message": "not found"}`)) // 傳輸 []byte 格式的資料
}
func main() {
http.HandleFunc("/", notFound) // 指定任何路徑下的都去呼叫 notFound 函式
http.ListenAndServe(":8000", nil) // 指定server監聽 port 8000
}
這裡加上例外處裡顯示像是port號已被其它程式占用或其他的錯誤訊息。
func main() {
http.HandleFunc("/", notFound)
err := http.ListenAndServe(":8000", nil)
if err != nil {
panic(err) // 如果有錯誤就終止程式
}
fmt.Println("The port 8000 is successfully connected")
}
階段二: 建立路由功能
雖然使用 net/http 可以實現路由功能,但日後若有更多功能要開發,這樣的設計方式會衍伸路由管理的麻煩,因此這個階段導入了一個路由設計的套件叫gorilla/mux。可以用這行指令$ go get -u github.com/gorilla/mux
取得這個套件。
import(
"net/http"
"github.com/gorilla/mux"
)
func get(w http.ResponseWriter, r *http.Request){
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"message": "get called"}`))
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/", get).Methods(http.MethodGet)
err := http.ListenAndServe(":8000", router)
if err != nil {
panic(err) // 如果有錯誤就終止程式
}
fmt.Println("The port 8000 is successfully connected")
}
引入"github.com/gorilla/mux" ,這裡我註冊了一條新url路徑並指給 get 處裡,註冊新 url的方式與 http.HandleFunc()一樣,若有符合路徑的請求就到對應的處裡器並傳入參數(http.ResponseWriter, *http.Request)。參考文件 另外,這裡在HandleFunc()之後綁定 HTTP的動作,所以同一個路徑會針對有不同HTTP動作執行相對應的處裡器。現在可以打開終端機,先輸入go run main.go
啟動go主程式,接著輸入curl -X GET localhost:8000/
就會看到 {message: get called} 的訊息了。
階段三: 設計 Web API
func main() {
router := mux.NewRouter()
api := router.PathPrefix("/api/v1").Subrouter()
api.HandleFunc("/", get).Methods(http.MethodGet)
err := http.ListenAndServe(":8000", router)
if err != nil {
panic(err) // 如果有錯誤就終止程式
}
fmt.Println("The port 8000 is successfully connected")
}
假如在我的server上有很多支API路徑,我希望透過不同的namespace來做管理。透過 mux 利用 PathPrefix("/api/v1").Subrouter(),篩選符合路徑的請求並做路徑分流。現在要輸入curl -X GET localhost:8000/api/v1/
才會看到 {message: get called} 的訊息。參考文件
之後可以加入其它像是POST、PUT、DELETE的動作來做不同的路由處裡。
完整範例參考