Re-enable API Gateway route handling (/api/gateway/...)
API Gateway routes are now bind under <base>/api/gateway. This also removes custom route method validation and handles not-found responses with a chi's NotFound method
This commit is contained in:
parent
0d429fa641
commit
6c8bec2c3c
@ -112,6 +112,9 @@ func (app *CortezaApp) mountHttpRoutes(r chi.Router) {
|
||||
|
||||
r.Handle("/docs", http.RedirectHandler(fullpathDocs+"/", http.StatusPermanentRedirect))
|
||||
r.Handle("/docs*", http.StripPrefix(fullpathDocs, http.FileServer(docs.GetFS())))
|
||||
|
||||
var fullpathGateway = options.CleanBase(ho.BaseUrl, ho.ApiBaseUrl, "gateway")
|
||||
r.Handle("/gateway*", http.StripPrefix(fullpathGateway, app.ApigwService))
|
||||
})
|
||||
}()
|
||||
|
||||
|
||||
@ -13,9 +13,11 @@ const (
|
||||
func helperDefaultResponse(opt *options.ApigwOpt) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if opt.LogEnabled {
|
||||
// Say something friendly when logging is enabled
|
||||
http.Error(w, devHelperResponseBody, http.StatusTeapot)
|
||||
} else {
|
||||
http.Error(w, ``, http.StatusFound)
|
||||
// Default 404 response
|
||||
http.Error(w, "", http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,12 +54,6 @@ func (r route) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
scope.Set("opts", r.opts)
|
||||
scope.Set("payload", body)
|
||||
|
||||
if err := r.validate(req); err != nil {
|
||||
r.log.Debug("error validating request on route", zap.Error(err))
|
||||
r.errHandler(w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
if r.opts.LogEnabled {
|
||||
o, _ := httputil.DumpRequest(req, r.opts.LogRequestBody)
|
||||
r.log.Debug("incoming request", zap.Any("request", string(o)))
|
||||
@ -74,14 +68,6 @@ func (r route) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
)
|
||||
}
|
||||
|
||||
func (r route) validate(req *http.Request) (err error) {
|
||||
if req.Method != r.method {
|
||||
err = fmt.Errorf("invalid method %s", req.Method)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r route) String() string {
|
||||
return fmt.Sprintf("%s %s", r.method, r.endpoint)
|
||||
}
|
||||
|
||||
@ -68,18 +68,6 @@ func Test_pl(t *testing.T) {
|
||||
expStatus: http.StatusTemporaryRedirect,
|
||||
expError: "{\"error\":{\"message\":\"test error\"}}\n",
|
||||
},
|
||||
{
|
||||
name: "request method validation fail",
|
||||
handler: &types.MockHandler{
|
||||
Handler_: func(rw http.ResponseWriter, r *http.Request) error {
|
||||
rw.WriteHeader(http.StatusTemporaryRedirect)
|
||||
return errors.New("test error")
|
||||
},
|
||||
},
|
||||
method: "GET",
|
||||
expStatus: http.StatusInternalServerError,
|
||||
expError: "{\"error\":{\"message\":\"invalid method POST\"}}\n",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -44,10 +44,6 @@ func Service() *apigw {
|
||||
return apiGw
|
||||
}
|
||||
|
||||
func Set(a *apigw) {
|
||||
apiGw = a
|
||||
}
|
||||
|
||||
// Setup handles the singleton service
|
||||
func Setup(opts *options.ApigwOpt, log *zap.Logger, storer storer) {
|
||||
if apiGw != nil {
|
||||
@ -74,6 +70,23 @@ func New(opts *options.ApigwOpt, logger *zap.Logger, storer storer) *apigw {
|
||||
//
|
||||
// When reloading routes, make sure to replace the original mux
|
||||
func (s *apigw) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if s.mx == nil {
|
||||
http.Error(w, "API Gateway not initialized", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if len(s.routes) == 0 {
|
||||
helperDefaultResponse(s.opts)(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Remove route context for chi
|
||||
//
|
||||
// Without this, chi can not properly handle requests
|
||||
// in API gateway's sub-router
|
||||
r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, nil))
|
||||
|
||||
// Handle api-gw request
|
||||
s.mx.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
@ -94,21 +107,25 @@ func (s *apigw) Reload(ctx context.Context) (err error) {
|
||||
|
||||
// Rebuild the mux
|
||||
s.mx = chi.NewMux()
|
||||
s.mx.HandleFunc("/", helperDefaultResponse(s.opts))
|
||||
|
||||
for _, r := range s.routes {
|
||||
s.mx.Handle(r.endpoint, r)
|
||||
// Register route handler on endpoint & method
|
||||
s.mx.Method(r.method, r.endpoint, r)
|
||||
}
|
||||
|
||||
// API GW 404 handler
|
||||
s.mx.NotFound(helperDefaultResponse(s.opts))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Init all the routes
|
||||
func (s *apigw) Init(ctx context.Context, route ...*route) {
|
||||
// Init all routes
|
||||
func (s *apigw) Init(ctx context.Context, routes ...*route) {
|
||||
var (
|
||||
defaultPostFilter types.Handler
|
||||
)
|
||||
|
||||
s.routes = route
|
||||
s.routes = routes
|
||||
|
||||
s.log.Debug("registering routes", zap.Int("count", len(s.routes)))
|
||||
|
||||
@ -138,17 +155,17 @@ func (s *apigw) Init(ctx context.Context, route ...*route) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, f := range regFilters {
|
||||
flog := log.With(zap.String("ref", f.Ref))
|
||||
for _, rf := range regFilters {
|
||||
flog := log.With(zap.String("ref", rf.Ref))
|
||||
|
||||
// make sure there is only one postfilter
|
||||
// on async routes
|
||||
if r.meta.async && f.Kind == string(types.PostFilter) {
|
||||
if r.meta.async && rf.Kind == string(types.PostFilter) {
|
||||
flog.Debug("not registering filter for async route")
|
||||
continue
|
||||
}
|
||||
|
||||
ff, err := s.registerFilter(f, r)
|
||||
ff, err := s.registerFilter(rf, r)
|
||||
|
||||
if err != nil {
|
||||
flog.Error("could not register filter", zap.Error(err))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user