其他框架的代码请参考GET方法main.go

时间:2019-09-30 15:30来源:快三平台下载编程
八个采用github.com/gorilla/mux完成REST API Service的例证,首要内容包罗: GET/POST方法,如何接受path参数,query参数,以及POST body参数 怎么样设置再次来到状态码,怎样回到JSON数据body 验证

八个采用github.com/gorilla/mux完成REST API Service的例证,首要内容包罗:

  1. GET/POST方法,如何接受path参数,query参数,以及POST body参数
  2. 怎么样设置再次来到状态码,怎样回到JSON数据body
  3. 验证Handler函数是联合的可能异步的,单线程的还是多线程的

GET方法

布告一个GET REST API,接收client须要,并分析U奇骏L带的查询参数,最后回到JSON数据。main.go

package mainimport ( "flag" "fmt" "log" "net/http" "github.com/gorilla/mux")var ( hostname string port int)/* register command line options */func init() { flag.StringVar(&hostname, "hostname", "0.0.0.0", "The hostname or IP on which the REST server will listen") flag.IntVar(&port, "port", 8080, "The port on which the REST server will listen")}func main() { flag.Parse() var address = fmt.Sprintf("%s:%d", hostname, port) log.Println("REST service listening on", address) // register router router := mux.NewRouter().StrictSlash router. HandleFunc("/api/service/get", MyGetHandler). Methods // start server listening err := http.ListenAndServe(address, router) if err != nil { log.Fatalln("ListenAndServe err:", err) } log.Println("Server end")}

handle.go

package mainimport ( "encoding/json" "fmt" "io/ioutil" "net/http" "github.com/gorilla/mux")func MyGetHandler(w http.ResponseWriter, r *http.Request) { // parse query parameter vals := r.URL.Query() param, _ := vals["servicename"] // get query parameters // composite response body var res = map[string]string{"result":"succ", "name":param[0]} response, _ := json.Marshal w.Header().Set("Content-Type", "application/json") w.Write}

运行

# on server$ go build && ./main 2017/09/16 15:04:23 REST service listening on 0.0.0.0:8080# on client$ curl -X GET http://localhost:8080/api/service/get?servicename=myname{"name":"myname","result":"succ"}

POST方法

其一例子client发送POST消息,并动用path变量,同一时间附带JSON格式body新闻体,server端分析body内容,并赶回JSON音讯。这里只交给POST相关代码,别的框架的代码请参见GET方法main.go

 // register router router := mux.NewRouter().StrictSlash router. HandleFunc("/api/service/get", MyGetHandler). Methods router. HandleFunc("/api/service/{servicename}/post", MyPostHandler). Methods

handle.go

func MyPostHandler(w http.ResponseWriter, r *http.Request) { // parse path variable vars := mux.Vars servicename := vars["servicename"] // parse JSON body var req map[string]interface{} body, _ := ioutil.ReadAll json.Unmarshal(body, &req) servicetype := req["servicetype"]. // composite response body var res = map[string]string{"result":"succ", "name":servicename, "type":servicetype} response, _ := json.Marshal w.Header().Set("Content-Type", "application/json") w.Write}

运行

$ curl -X POST -d '{"servicetype":"mytype"}' http://localhost:8080/api/service/myservice/post{"name":"myservice","result":"succ","type":"mytype"}

HTTP 返回值

上边例子重临的都以200 OK,怎么着得以依靠服务运作状态再次回到不相同的状态码呢?以GET方法为例handler.go

func MyGetHandler(w http.ResponseWriter, r *http.Request) { var res map[string]string = make(map[string]string) var status = http.StatusOK vals := r.URL.Query() param, ok := vals["name"] if  { res["result"] = "fail" res["error"] = "required parameter name is missing" status = http.StatusBadRequest } else { res["result"] = "succ" res["name"] = param[0] status = http.StatusOK } response, _ := json.Marshal w.WriteHeader w.Header().Set("Content-Type", "application/json") w.Write}

运作结果

  • 先是个央求,重返200 OK
$ curl -v -X GET http://localhost:8080/api/service/get?name=myname* Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8080 > GET /api/service/get?name=myname HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.43.0> Accept: */*> < HTTP/1.1 200 OK< Date: Sat, 16 Sep 2017 07:41:38 GMT< Content-Length: 33< Content-Type: text/plain; charset=utf-8< * Connection #0 to host localhost left intact{"name":"myname","result":"succ"}
  • 其次个要求,再次来到400 Bad Request
$ curl -v -X GET http://localhost:8080/api/service/get* Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8080 > GET /api/service/get HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.43.0> Accept: */*> < HTTP/1.1 400 Bad Request< Date: Sat, 16 Sep 2017 07:41:42 GMT< Content-Length: 62< Content-Type: text/plain; charset=utf-8< * Connection #0 to host localhost left intact{"error":"required parameter name is missing","result":"fail"} 

Handler函数是同台的或许异步的

在前面包车型大巴事例中大家看来了,w http.ResponseWriter能够用来安装重临新闻的Status值,Header音信,以及Body内容,假诺大家怎样也不做,会出怎么着结果吧,验证handler.go

func MyGetHandler(w http.ResponseWriter, r *http.Request) { // do nothing}

测试

$ curl -v -X GET http://localhost:8080/api/service/get?name=myname* Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8080 > GET /api/service/get?name=myname HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.43.0> Accept: */*> < HTTP/1.1 200 OK< Date: Sat, 16 Sep 2017 07:50:18 GMT< Content-Length: 0< Content-Type: text/plain; charset=utf-8< * Connection #0 to host localhost left intact

能够见到client符合规律的接受了200 OK的再次回到码。

再做叁个例子,让Handler sleep一段时间

func MyGetHandler(w http.ResponseWriter, r *http.Request) { time.Sleep(5*time.Second);}

客户端

$ time curl -v -X GET http://localhost:8080/api/service/get?name=myname* Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8080 > GET /api/service/get?name=myname HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.43.0> Accept: */*> < HTTP/1.1 200 OK< Date: Sat, 16 Sep 2017 07:56:12 GMT< Content-Length: 0< Content-Type: text/plain; charset=utf-8< * Connection #0 to host localhost left intactreal 0m5.081suser 0m0.005ssys 0m0.009s

能够见到client在5秒现在常常的归来了,那么我们的结论是Handler函数重临的时候,client也就吸收接纳了server的回来;所以handler是二个共同调用函数。然后随即大家当然想到另一个主题材料。

Handler函数是单线程的依旧多线程的

第一个难题,不一样的handler能还是不可能同期跻身handler.go

func MyGetHandler(w http.ResponseWriter, r *http.Request) { log.Println("entry of MyGetHandler") time.Sleep(10*time.Second); log.Println("exit of MyGetHandler")}func MyPostHandler(w http.ResponseWriter, r *http.Request) { log.Println("entry of MyPostHandler") time.Sleep(2*time.Second); log.Println("exit of MyPostHandler")}

测验打开多少个极端,一个周转server,一个调用MyGetHander,另三个调用 MyPostHandler。终端1: server

2017/09/16 16:12:32 entry of MyGetHandler2017/09/16 16:12:35 entry of MyPostHandler2017/09/16 16:12:37 exit of MyPostHandler2017/09/16 16:12:42 exit of MyGetHandler

终端2: MyGetHandler

$ date && time curl -X GET http://localhost:8080/api/service/get?name=mynameSat Sep 16 16:12:32 CST 2017real 0m10.020suser 0m0.006ssys 0m0.006s

终端2: MyPostHandler

$ date && time curl -X POST -d '{"servicetype":"mytype"}' http://localhost:8080/api/service/myservice/postSat Sep 16 16:12:35 CST 2017real 0m2.017suser 0m0.005ssys 0m0.005s

通过相比较时间戳,我们能够窥见GetHandler已经在管理了,此时PostHandler刚进来,然后PostHander退出后,GetHander再脱离,由此不一致的Handler的实践办法是二十十二线程的,五个恳求能够冲入。

第一个难点,同一个handler能还是无法同有的时候间步入handler.go

func MyGetHandler(w http.ResponseWriter, r *http.Request) { log.Println("entry of MyGetHandler") vals := r.URL.Query() param, ok := vals["name"] if  { log.Println("name=", param[0]) } time.Sleep(5*time.Second); log.Println("exit of MyGetHandler")}

测验和率先个难点一样选拔多少个终端终端1: server

2017/09/16 16:18:17 entry of MyGetHandler2017/09/16 16:18:17 name= myname12017/09/16 16:18:19 entry of MyGetHandler2017/09/16 16:18:19 name= myname22017/09/16 16:18:22 exit of MyGetHandler2017/09/16 16:18:24 exit of MyGetHandler

终端2: MyGetHandler

$ date && time curl -X GET http://localhost:8080/api/service/get?name=myname1Sat Sep 16 16:18:17 CST 2017real 0m5.032suser 0m0.005ssys 0m0.009s

终端2: MyPostHandler

$ date && time curl -X GET http://localhost:8080/api/service/get?name=myname2Sat Sep 16 16:18:19 CST 2017real 0m5.021suser 0m0.006ssys 0m0.006s

结论是同多少个Handler函数也是能够重入的。

编辑:快三平台下载编程 本文来源:其他框架的代码请参考GET方法main.go

关键词: