设为首页 加入收藏

TOP

Golang:使用 httprouter 构建 API 服务器(二)
2017-10-21 06:06:53 】 浏览:2031
Tags:Golang 使用 httprouter 构建 API 服务器
esponse := JsonResponse{Data: book} if err := json.NewEncoder(w).Encode(response); err != nil { panic(err) } } func main() { router := httprouter.New() router.GET("/", Index) router.GET("/books", BookIndex) router.GET("/books/:isdn", BookShow) // Create a couple of sample Book entries bookstore["123"] = &Book{ ISDN: "123", Title: "Silence of the Lambs", Author: "Thomas Harris", Pages: 367, } bookstore["124"] = &Book{ ISDN: "124", Title: "To Kill a Mocking Bird", Author: "Harper Lee", Pages: 320, } log.Fatal(http.ListenAndServe(":8080", router)) }

如果您现在尝试请求 GET https:// localhost:8080/books,您将得到以下响应:

{
    "meta": null,
    "data": [
        {
            "isdn": "123",
            "title": "Silence of the Lambs",
            "author": "Thomas Harris",
            "pages": 367
        },
        {
            "isdn": "124",
            "title": "To Kill a Mocking Bird",
            "author": "Harper Lee",
            "pages": 320
        }
    ]
}

我们在 main 函数中硬编码了这两个 book 实体。点击这里[2]获取当前阶段的代码。

让我们来重构一下代码。 到目前为止,我们所有的代码都放置在同一个文件中:main.go。我们可以把它们移到各个单独的文件中。此时我们有一个目录:

.
├── handlers.go
├── main.go
├── models.go
└── responses.go

我们把所有与 JSON 响应相关的结构体移动到 responses.go,将 handler 函数移动到 Handlers.go,且将 Book 结构体移动到 models.go。点击这里[3]查看当前阶段的代码。 现在,我们跳过来写一些测试。在 Go 中,*_test.go 文件是用于测试的。因此让我们创建一个 handlers_test.go

package main

import (
    "net/http"
    "net/http/httptest"
    "testing"

    "github.com/julienschmidt/httprouter"
)

func TestBookIndex(t *testing.T) {
    // Create an entry of the book to the bookstore map
    testBook := &Book{
        ISDN:   "111",
        Title:  "test title",
        Author: "test author",
        Pages:  42,
    }
    bookstore["111"] = testBook
    // A request with an existing isdn
    req1, err := http.NewRequest("GET", "/books", nil)
    if err != nil {
        t.Fatal(err)
    }
    rr1 := newRequestRecorder(req1, "GET", "/books", BookIndex)
    if rr1.Code != 200 {
        t.Error("Expected response code to be 200")
    }
    // expected response
    er1 := "{\"meta\":null,\"data\":[{\"isdn\":\"111\",\"title\":\"test title\",\"author\":\"test author\",\"pages\":42}]}\n"
    if rr1.Body.String() != er1 {
        t.Error("Response body does not match")
    }
}

// Mocks a handler and returns a httptest.ResponseRecorder
func newRequestRecorder(req *http.Request, method string, strPath string, fnHandler func(w http.ResponseWriter, r *http.Request, param httprouter.Params)) *httptest.ResponseRecorder {
    router := httprouter.New()
    router.Handle(method, strPath, fnHandler)
    // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
    rr := httptest.NewRecorder()
    // Our handlers satisfy http.Handler, so we can call their ServeHTTP method
    // directly and pass in our Request and ResponseRecorder.
    router.ServeHTTP(rr, req)
    return rr
}

我们使用 httptest 包的 Recorder 来 mock handler。同样,您也可以为 handler BookShow 编写测试。
让我们稍微做些重构。我们仍然把所有路由都定义在了 main 函数中,handler 看起来有点臃肿,我们可以做点 DRY,我们

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇golang单例模式 下一篇Go语言备忘录(3):net/http包的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目