Files
fn-serverless/api/server/extension_points.go
Reed Allman a8a3e143c7 unexport all data abstractions on Server (#618)
this patch has no behavior changes, changes are:

* server.Datastore() -> server.datastore
* server.MQ -> server.mq
* server.LogDB -> server.logstore
* server.Agent -> server.agent

these were at a minimum not uniform. further, it's probably better to force
configuration through initialization in `server.New` to ensure thread safety
of referencing if someone does want to modify these as well as forcing things
into our initialization path and reducing the surface area of the Server
abstraction.
2017-12-21 13:21:02 -06:00

106 lines
3.2 KiB
Go

// TODO: it would be nice to move these into the top level folder so people can use these with the "functions" package, eg: functions.ApiHandler
package server
import (
"net/http"
"github.com/fnproject/fn/api"
"github.com/fnproject/fn/api/models"
"github.com/fnproject/fn/fnext"
"github.com/gin-gonic/gin"
)
func (s *Server) apiHandlerWrapperFunc(apiHandler fnext.ApiHandler) gin.HandlerFunc {
return func(c *gin.Context) {
apiHandler.ServeHTTP(c.Writer, c.Request)
}
}
func (s *Server) apiAppHandlerWrapperFunc(apiHandler fnext.ApiAppHandler) gin.HandlerFunc {
return func(c *gin.Context) {
// get the app
appName := c.Param(api.CApp)
app, err := s.datastore.GetApp(c.Request.Context(), appName)
if err != nil {
handleErrorResponse(c, err)
c.Abort()
return
}
if app == nil {
handleErrorResponse(c, models.ErrAppsNotFound)
c.Abort()
return
}
apiHandler.ServeHTTP(c.Writer, c.Request, app)
}
}
func (s *Server) apiRouteHandlerWrapperFunc(apiHandler fnext.ApiRouteHandler) gin.HandlerFunc {
return func(c *gin.Context) {
context := c.Request.Context()
// get the app
appName := c.Param(api.CApp)
app, err := s.datastore.GetApp(context, appName)
if err != nil {
handleErrorResponse(c, err)
c.Abort()
return
}
if app == nil {
handleErrorResponse(c, models.ErrAppsNotFound)
c.Abort()
return
}
// get the route TODO
routePath := "/" + c.Param(api.CRoute)
route, err := s.datastore.GetRoute(context, appName, routePath)
if err != nil {
handleErrorResponse(c, err)
c.Abort()
return
}
if route == nil {
handleErrorResponse(c, models.ErrRoutesNotFound)
c.Abort()
return
}
apiHandler.ServeHTTP(c.Writer, c.Request, app, route)
}
}
// AddEndpoint adds an endpoint to /v1/x
func (s *Server) AddEndpoint(method, path string, handler fnext.ApiHandler) {
v1 := s.Router.Group("/v1")
// v1.GET("/apps/:app/log", logHandler(cfg))
v1.Handle(method, path, s.apiHandlerWrapperFunc(handler))
}
// AddEndpoint adds an endpoint to /v1/x
func (s *Server) AddEndpointFunc(method, path string, handler func(w http.ResponseWriter, r *http.Request)) {
s.AddEndpoint(method, path, fnext.ApiHandlerFunc(handler))
}
// AddAppEndpoint adds an endpoints to /v1/apps/:app/x
func (s *Server) AddAppEndpoint(method, path string, handler fnext.ApiAppHandler) {
v1 := s.Router.Group("/v1")
v1.Handle(method, "/apps/:app"+path, s.apiAppHandlerWrapperFunc(handler))
}
// AddAppEndpoint adds an endpoints to /v1/apps/:app/x
func (s *Server) AddAppEndpointFunc(method, path string, handler func(w http.ResponseWriter, r *http.Request, app *models.App)) {
s.AddAppEndpoint(method, path, fnext.ApiAppHandlerFunc(handler))
}
// AddRouteEndpoint adds an endpoints to /v1/apps/:app/routes/:route/x
func (s *Server) AddRouteEndpoint(method, path string, handler fnext.ApiRouteHandler) {
v1 := s.Router.Group("/v1")
v1.Handle(method, "/apps/:app/routes/:route"+path, s.apiRouteHandlerWrapperFunc(handler)) // conflicts with existing wildcard
}
// AddRouteEndpoint adds an endpoints to /v1/apps/:app/routes/:route/x
func (s *Server) AddRouteEndpointFunc(method, path string, handler func(w http.ResponseWriter, r *http.Request, app *models.App, route *models.Route)) {
s.AddRouteEndpoint(method, path, fnext.ApiRouteHandlerFunc(handler))
}