/
api.go
78 lines (71 loc) · 2.07 KB
/
api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Package httpgateway provides an http-rpc handler which provides the entire http request over rpc
package httpgateway
import (
"context"
"github.com/liangdas/mqant/httpgateway/api"
"github.com/liangdas/mqant/httpgateway/errors"
"github.com/liangdas/mqant/httpgateway/proto"
"github.com/liangdas/mqant/module"
"github.com/liangdas/mqant/rpc"
"net/http"
)
//APIHandler 网关handler
type APIHandler struct {
Opts Options
App module.App
}
// API handler is the default handler which takes api.Request and returns api.Response
func (a *APIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
request, err := httpgatewayapi.RequestToProto(r)
if err != nil {
er := errors.InternalServerError("httpgateway", err.Error())
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(500)
w.Write([]byte(er.Error()))
return
}
server, err := a.Opts.Route(a.App, r)
if err != nil {
er := errors.InternalServerError("httpgateway", err.Error())
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(500)
w.Write([]byte(er.Error()))
return
}
rsp := &go_api.Response{}
ctx, _ := context.WithTimeout(context.TODO(), a.Opts.TimeOut)
if err = mqrpc.Proto(rsp, func() (reply interface{}, errstr interface{}) {
return server.SrvSession.Call(ctx, server.Hander, request)
}); err != nil {
w.Header().Set("Content-Type", "application/json")
ce := errors.Parse(err.Error())
switch ce.Code {
case 0:
w.WriteHeader(500)
default:
w.WriteHeader(int(ce.Code))
}
_, err = w.Write([]byte(ce.Error()))
return
} else if rsp.StatusCode == 0 {
rsp.StatusCode = http.StatusOK
}
for _, header := range rsp.GetHeader() {
for _, val := range header.Values {
w.Header().Add(header.Key, val)
}
}
if len(w.Header().Get("Content-Type")) == 0 {
w.Header().Set("Content-Type", "application/json")
}
w.WriteHeader(int(rsp.StatusCode))
w.Write([]byte(rsp.Body))
}
// NewHandler 创建网关
func NewHandler(app module.App, opts ...Option) http.Handler {
options := NewOptions(app, opts...)
return &APIHandler{
Opts: options,
App: app,
}
}