Skip to main content

Middlewares

Gleece provides middleware support for request processing.

Middleware events can be triggered at three distinct points:

  • Operational Events
    • beforeOperation: Executes before the operation/function
    • afterOperationSuccess: Executes after successful operation completion
  • Error Events
    • onInputValidationError: Triggered when input validation fails
    • onOperationError: Triggered after operation failure
    • onOutputValidationError: Triggered when output validation fails (output validation is disabled by default, see Validating Response Payloads)

Each middleware receives the router's context (specific to the engine in use).

For error events, the middleware also receives the error instance.

Middlewares return a ctx that will be used as the context in subsequent middlewares and route handlers and a boolean value that determines the flow of execution:

  • true: Continue with the normal execution flow
  • false: Abort execution (typically used when the response has been handled within the middleware)

Implementing Middleware

middlewares.go
// For Gin
func MyMiddleware(ctx context.Context, ginCtx *gin.Context) (context.Context, bool) {
return ctx, true
}

// For Echo
func MyMiddleware(ctx context.Context, echoCtx echo.Context) (context.Context, bool) {
return ctx, true
}

// For Fiber
func MyMiddleware(ctx context.Context, fiberCtx *fiber.Ctx) (context.Context, bool) {
return ctx, true
}

// For Gorilla Mux & Chi
func MyMiddleware(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool) {
return ctx, true
}

And similarly for errors middlewares:

middlewares.go
// For Gin
func MyErrorMiddleware(ctx context.Context, ginCtx *gin.Context, err error) (context.Context, bool) {
return ctx, true
}

// For Echo
func MyErrorMiddleware(ctx context.Context, echoCtx echo.Context, err error) (context.Context, bool) {
return ctx, true
}

// For Fiber
func MyErrorMiddleware(ctx context.Context, fiberCtx *fiber.Ctx, err error) (context.Context, bool) {
return ctx, true
}

// For Gorilla Mux & Chi
func MyErrorMiddleware(ctx context.Context, w http.ResponseWriter, r *http.Request, err error) (context.Context, bool) {
return ctx, true
}

Registering Middleware

Use the generated code's RegisterMiddleware / RegisterErrorMiddleware API to register your middleware functions.

Example:

main.go
package main

import (
"context"
"net/http"
"time"

gleeceRoutes "<package>"

"github.com/gopher-fleece/runtime"
"github.com/gin-gonic/gin"
)

const arriveTimeKey ctxKey = "arrive-time"

func LogBeforeOperationMiddleware(ctx context.Context, ginCtx *gin.Context) (context.Context, bool) {
println("Method:", ginCtx.Request.Method, "Path:", ctx.Request.URL.Path, "arrived")
ctx = context.WithValue(ctx, arriveTimeKey, time.Now())
return ctx, true
}

func LogAfterOperationSuccessMiddleware(ctx context.Context, ginCtx *gin.Context) (context.Context, bool) {
if arrive, ok := ctx.Value(arriveTimeKey).(time.Time); ok {
println("Method:", ginCtx.Request.Method, "Path:", ginCtx.Request.URL.Path, "completed in ", time.Since(arrive))
}
return ctx, true
}

func LogOnErrorMiddleware(ctx context.Context, ginCtx *gin.Context, err error) (context.Context, bool) {
println("Method:", ginCtx.Request.Method, "Path:", ginCtx.Request.URL.Path, "failed with error:", err.Error())
return ctx, true
}

func main() {
// Create a default Gin router
router := gin.Default()

// Register the middlewares
gleeceRoutes.RegisterMiddleware(runtime.BeforeOperation, LogBeforeOperationMiddleware)
gleeceRoutes.RegisterMiddleware(runtime.AfterOperationSuccess, LogAfterOperationSuccessMiddleware)
gleeceRoutes.RegisterErrorMiddleware(runtime.OnOperationError, LogOnErrorMiddleware)

// Register the routes from the generated code
gleeceRoutes.RegisterRoutes(router)

// Start the server on port 8080
router.Run("127.0.0.1:8080")
}

You can register any number of middleware functions. They will be executed in the order of registration.

When a middleware returns false, it halts the execution chain, preventing any remaining middleware from running.