Skip to content

Commit

Permalink
更新到新的 jsonpi 介面
Browse files Browse the repository at this point in the history
新的 jsonapi 介面是根據一個 GopherCon 2016 的演講進行的優化,投影片在
http://go-talks.appspot.com/github.com/broady/talks/web-frameworks-gophercon.slide
  • Loading branch information
Ronmi committed Jul 19, 2016
1 parent 56fbcea commit ad10bcb
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 71 deletions.
20 changes: 6 additions & 14 deletions cmd/xchg/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,31 @@ type add struct {
A Authenticator
}

func (h *add) Handle(enc *json.Encoder, dec *json.Decoder, httpData *jsonapi.HTTP) {
func (h *add) Handle(dec *json.Decoder, httpData *jsonapi.HTTP) (ret interface{}, err error) {
type p struct {
Data Order `json:"data"`
Token string `json:"token"`
}

var param p
if err := dec.Decode(&param); err != nil {
httpData.WriteHeader(http.StatusBadRequest)
enc.Encode("Parameter is not Order object")
return
return nil, jsonapi.Error{http.StatusBadRequest, "Parameter is not Order object"}
}

if !h.A.Valid(param.Token) {
httpData.WriteHeader(http.StatusForbidden)
enc.Encode("Invalid token")
return
return nil, jsonapi.Error{http.StatusForbidden, "Invalid token"}
}

// validating data
data := param.Data
data.Code = strings.ToUpper(strings.TrimSpace(data.Code))
if len(data.Code) != 3 || data.Local == 0 || data.Foreign == 0 || data.Time <= 0 {
httpData.WriteHeader(http.StatusBadRequest)
enc.Encode("Parameter has no Order object")
return
return nil, jsonapi.Error{http.StatusBadRequest, "Parameter has no Order object"}
}

if _, err := h.M.Insert("orders", data); err != nil {
httpData.WriteHeader(http.StatusInternalServerError)
enc.Encode(fmt.Sprintf("Error saving order: %s", err))
return
return nil, jsonapi.Error{http.StatusInternalServerError, fmt.Sprintf("Error saving order: %s", err)}
}

enc.Encode(nil)
return
}
10 changes: 5 additions & 5 deletions cmd/xchg/add_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestAddOK(t *testing.T) {
h, token, mgr := makeAdd([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post(
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post(
"/api/add",
"",
`{"data":{"when":1468248043,"foreign":100,"local":-100,"code":"AUD"},"token":"`+token+`"}`,
Expand Down Expand Up @@ -77,7 +77,7 @@ func TestAddDuplicated(t *testing.T) {
h, token, mgr := makeAdd(presetData)
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post(
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post(
"/api/add",
"",
`{"data":{"when":1468248039,"foreign":100,"local":-100,"code":"USD"},"token":"`+token+`"}`,
Expand All @@ -96,7 +96,7 @@ func TestAddNoData(t *testing.T) {
h, token, mgr := makeAdd([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/add", "", `{"token":"`+token+`"}`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/add", "", `{"token":"`+token+`"}`)

if err != nil {
t.Fatalf("unexpected error occured when testing add: %s", err)
Expand All @@ -111,7 +111,7 @@ func TestAddNotJSON(t *testing.T) {
h, _, mgr := makeAdd([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/add", "", `1234`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/add", "", `1234`)

if err != nil {
t.Fatalf("unexpected error occured when testing add: %s", err)
Expand All @@ -126,7 +126,7 @@ func TestAddWrongToken(t *testing.T) {
h, _, mgr := makeAdd([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post(
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post(
"/api/add",
"",
`{"data":{"when":1468248043,"foreign":100,"local":-100,"code":"AUD"},"token":"1234"}`,
Expand Down
16 changes: 7 additions & 9 deletions cmd/xchg/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ type auth struct {
}

// 錯誤處理會重複使用,抽出來
func (h *auth) e(enc *json.Encoder, httpData *jsonapi.HTTP, msg string) {
httpData.WriteHeader(http.StatusBadRequest)
enc.Encode(msg)
return
func (h *auth) e(msg string) jsonapi.Error {
return jsonapi.Error{http.StatusBadRequest, msg}
}

func (h *auth) Handle(enc *json.Encoder, dec *json.Decoder, httpData *jsonapi.HTTP) {
func (h *auth) Handle(dec *json.Decoder, httpData *jsonapi.HTTP) (ret interface{}, err error) {
// 定義參數型別
type p struct {
Pin string `json:"pin"`
Expand All @@ -28,17 +26,17 @@ func (h *auth) Handle(enc *json.Encoder, dec *json.Decoder, httpData *jsonapi.HT

// 同樣的錯誤會在這個方法裡重複使用,所以拉出來

if err := dec.Decode(&param); err != nil {
h.e(enc, httpData, "Parameter is not Pin object")
if err = dec.Decode(&param); err != nil {
err = h.e("Parameter is not Pin object")
return
}

// validating data
token, err := h.A.Token(param.Pin)
if err != nil {
h.e(enc, httpData, "Pin code incorrect")
err = h.e("Pin code incorrect")
return
}

enc.Encode(token)
return token, nil
}
4 changes: 2 additions & 2 deletions cmd/xchg/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestAuthOK(t *testing.T) {
fake := FakeAuthenticator("123456")
h := &auth{fake}

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/auth", "", `{"pin":"123456"}`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/auth", "", `{"pin":"123456"}`)

if err != nil {
t.Fatalf("unexpected error occured when testing auth: %s", err)
Expand Down Expand Up @@ -40,7 +40,7 @@ func TestAuthWrongPin(t *testing.T) {
}

for _, c := range cases {
resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/auth", "", c.in)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/auth", "", c.in)

if err != nil {
t.Fatalf("unexpected error occured when testing auth: %s", err)
Expand Down
24 changes: 9 additions & 15 deletions cmd/xchg/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,25 @@ type list struct {
A Authenticator
}

func (h *list) Handle(enc *json.Encoder, dec *json.Decoder, httpData *jsonapi.HTTP) {
func (h *list) Handle(dec *json.Decoder, httpData *jsonapi.HTTP) (result interface{}, err error) {
type p struct {
Code string `json:"code"`
Token string `json:"token"`
}

var param p
if err := dec.Decode(&param); err != nil {
httpData.WriteHeader(http.StatusBadRequest)
enc.Encode(fmt.Sprintf("Error decoding parameter: %s", err))
if err = dec.Decode(&param); err != nil {
err = jsonapi.Error{http.StatusBadRequest, fmt.Sprintf("Error decoding parameter: %s", err)}
return
}

if !h.A.Valid(param.Token) {
httpData.WriteHeader(http.StatusForbidden)
enc.Encode("Invalid token")
err = jsonapi.Error{http.StatusForbidden, "Invalid token"}
return
}

if param.Code == "" {
httpData.WriteHeader(http.StatusBadRequest)
enc.Encode("You must pass currency code to me.")
err = jsonapi.Error{http.StatusBadRequest, "You must pass currency code to me."}
return
}

Expand All @@ -50,14 +47,11 @@ func (h *list) Handle(enc *json.Encoder, dec *json.Decoder, httpData *jsonapi.HT
ret = append(ret, o)
}

if err := rows.Err(); err != nil {
httpData.WriteHeader(http.StatusInternalServerError)
enc.Encode(fmt.Sprintf("Error reading data from database: %s", err))
if err = rows.Err(); err != nil {
err = jsonapi.Error{http.StatusInternalServerError, fmt.Sprintf("Error reading data from database: %s", err)}
return
}

if err := enc.Encode(ret); err != nil {
httpData.WriteHeader(http.StatusInternalServerError)
enc.Encode(fmt.Sprintf("Error formatting data: %s", err))
}
return ret, nil

}
10 changes: 5 additions & 5 deletions cmd/xchg/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestList(t *testing.T) {
h, token, mgr := makeList(presetUSD)
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post(
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post(
"/api/list",
"",
`{"code":"USD","token":"`+token+`"}`,
Expand Down Expand Up @@ -62,7 +62,7 @@ func TestListEmpty(t *testing.T) {
h, token, mgr := makeList([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/list", "", `{"code":"NTD","token":"`+token+`"}`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/list", "", `{"code":"NTD","token":"`+token+`"}`)

if err != nil {
t.Fatalf("unexpected error occured when testing list: %s", err)
Expand All @@ -84,7 +84,7 @@ func TestListNoData(t *testing.T) {
h, token, mgr := makeList([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/list", "", `{"token":"`+token+`"}`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/list", "", `{"token":"`+token+`"}`)

if err != nil {
t.Fatalf("unexpected error occured when testing list: %s", err)
Expand All @@ -99,7 +99,7 @@ func TestListNotJSON(t *testing.T) {
h, _, mgr := makeList([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/list", "", ``)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/list", "", ``)

if err != nil {
t.Fatalf("unexpected error occured when testing list: %s", err)
Expand All @@ -114,7 +114,7 @@ func TestListWrongToken(t *testing.T) {
h, _, mgr := makeList([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post(
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post(
"/api/list",
"",
`{"code":"USD","token":"1234"}`,
Expand Down
20 changes: 7 additions & 13 deletions cmd/xchg/listall.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,19 @@ type listall struct {
A Authenticator
}

func (h *listall) Handle(enc *json.Encoder, dec *json.Decoder, httpData *jsonapi.HTTP) {
func (h *listall) Handle(dec *json.Decoder, httpData *jsonapi.HTTP) (result interface{}, err error) {
type p struct {
Token string `json:"token"`
}

var param p
if err := dec.Decode(&param); err != nil {
httpData.WriteHeader(http.StatusBadRequest)
enc.Encode(fmt.Sprintf("Error decoding parameter: %s", err))
if err = dec.Decode(&param); err != nil {
err = jsonapi.Error{http.StatusBadRequest, fmt.Sprintf("Error decoding parameter: %s", err)}
return
}

if !h.A.Valid(param.Token) {
httpData.WriteHeader(http.StatusForbidden)
enc.Encode("Invalid token")
err = jsonapi.Error{http.StatusForbidden, "Invalid token"}
return
}

Expand All @@ -42,14 +40,10 @@ func (h *listall) Handle(enc *json.Encoder, dec *json.Decoder, httpData *jsonapi
ret = append(ret, o)
}

if err := rows.Err(); err != nil {
httpData.WriteHeader(http.StatusInternalServerError)
enc.Encode(fmt.Sprintf("Error reading data from database: %s", err))
if err = rows.Err(); err != nil {
err = jsonapi.Error{http.StatusInternalServerError, fmt.Sprintf("Error reading data from database: %s", err)}
return
}

if err := enc.Encode(ret); err != nil {
httpData.WriteHeader(http.StatusInternalServerError)
enc.Encode(fmt.Sprintf("Error formatting data: %s", err))
}
return ret, nil
}
8 changes: 4 additions & 4 deletions cmd/xchg/listall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestListAll(t *testing.T) {
h, token, mgr := makeListAll(presetData)
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/listall", "", `{"token":"`+token+`"}`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/listall", "", `{"token":"`+token+`"}`)

if err != nil {
t.Fatalf("unexpected error occured when testing listall: %s", err)
Expand Down Expand Up @@ -60,7 +60,7 @@ func TestListAllEmpty(t *testing.T) {
h, token, mgr := makeListAll([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/listall", "", `{"token":"`+token+`"}`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/listall", "", `{"token":"`+token+`"}`)

if err != nil {
t.Fatalf("unexpected error occured when testing listall: %s", err)
Expand All @@ -82,7 +82,7 @@ func TestListAllNotJSON(t *testing.T) {
h, _, mgr := makeListAll([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/listall", "", `1234`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/listall", "", `1234`)

if err != nil {
t.Fatalf("unexpected error occured when testing listall: %s", err)
Expand All @@ -97,7 +97,7 @@ func TestListAllWrongToken(t *testing.T) {
h, _, mgr := makeListAll([]Order{})
defer mgr.Connection().Close()

resp, err := jsonapi.HandlerTest(h.Handle).Post("/api/listall", "", `{"token":"1234"}`)
resp, err := jsonapi.HandlerTest(jsonapi.APIHandler(h.Handle).Handler).Post("/api/listall", "", `{"token":"1234"}`)

if err != nil {
t.Fatalf("unexpected error occured when testing listall: %s", err)
Expand Down
13 changes: 9 additions & 4 deletions cmd/xchg/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,15 @@ func main() {
}

mgr := sdm.New(db)
jsonapi.HandleFunc("/api/auth", (&auth{authmgr}).Handle)
jsonapi.HandleFunc("/api/listall", (&listall{mgr, authmgr}).Handle)
jsonapi.HandleFunc("/api/list", (&list{mgr, authmgr}).Handle)
jsonapi.HandleFunc("/api/add", (&add{mgr, authmgr}).Handle)
jsonapi.Register(
[]jsonapi.API{
jsonapi.API{"/api/auth", (&auth{authmgr}).Handle},
jsonapi.API{"/api/listall", (&listall{mgr, authmgr}).Handle},
jsonapi.API{"/api/list", (&list{mgr, authmgr}).Handle},
jsonapi.API{"/api/add", (&add{mgr, authmgr}).Handle},
},
nil,
)

// serve ui files
http.Handle("/node_modules/", http.FileServer(http.Dir(uidir)))
Expand Down

0 comments on commit ad10bcb

Please sign in to comment.