Simplify middleware

pull/3380/head
Juan Calderon-Perez 2025-03-29 15:58:24 -04:00 committed by GitHub
parent e90fe8afbc
commit a6572aff7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 40 additions and 43 deletions

View File

@ -27,7 +27,7 @@ Liveness, readiness and startup probes middleware for [Fiber](https://github.com
## Signatures ## Signatures
```go ```go
func NewHealthChecker(config Config) fiber.Handler func New(config Config) fiber.Handler
``` ```
## Examples ## Examples
@ -41,38 +41,38 @@ import(
) )
``` ```
After you initiate your [Fiber](https://github.com/gofiber/fiber) app, you can use the following possibilities: After you initiate your [Fiber](https://github.com/gofiber/fiber) app, you can use the following options:
```go ```go
// Provide a minimal config for liveness check // Provide a minimal config for liveness check
app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.NewHealthChecker()) app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.New())
// Provide a minimal config for readiness check // Provide a minimal config for readiness check
app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.NewHealthChecker()) app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.New())
// Provide a minimal config for startup check // Provide a minimal config for startup check
app.Get(healthcheck.DefaultStartupEndpoint, healthcheck.NewHealthChecker()) app.Get(healthcheck.DefaultStartupEndpoint, healthcheck.New())
// Provide a minimal config for check with custom endpoint // Provide a minimal config for check with custom endpoint
app.Get("/live", healthcheck.NewHealthChecker()) app.Get("/live", healthcheck.New())
// Or extend your config for customization // Or extend your config for customization
app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.New(healthcheck.Config{
Probe: func(c fiber.Ctx) bool { Probe: func(c fiber.Ctx) bool {
return true return true
}, },
})) }))
// And it works the same for readiness, just change the route // And it works the same for readiness, just change the route
app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.New(healthcheck.Config{
Probe: func(c fiber.Ctx) bool { Probe: func(c fiber.Ctx) bool {
return true return true
}, },
})) }))
// And it works the same for startup, just change the route // And it works the same for startup, just change the route
app.Get(healthcheck.DefaultStartupEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ app.Get(healthcheck.DefaultStartupEndpoint, healthcheck.New(healthcheck.Config{
Probe: func(c fiber.Ctx) bool { Probe: func(c fiber.Ctx) bool {
return true return true
}, },
})) }))
// With a custom route and custom probe // With a custom route and custom probe
app.Get("/live", healthcheck.NewHealthChecker(healthcheck.Config{ app.Get("/live", healthcheck.New(healthcheck.Config{
Probe: func(c fiber.Ctx) bool { Probe: func(c fiber.Ctx) bool {
return true return true
}, },
@ -81,7 +81,7 @@ app.Get("/live", healthcheck.NewHealthChecker(healthcheck.Config{
// It can also be used with app.All, although it will only respond to requests with the GET method // It can also be used with app.All, although it will only respond to requests with the GET method
// in case of calling the route with any method which isn't GET, the return will be 404 Not Found when app.All is used // in case of calling the route with any method which isn't GET, the return will be 404 Not Found when app.All is used
// and 405 Method Not Allowed when app.Get is used // and 405 Method Not Allowed when app.Get is used
app.All(healthcheck.DefaultReadinessEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ app.All(healthcheck.DefaultReadinessEndpoint, healthcheck.New(healthcheck.Config{
Probe: func(c fiber.Ctx) bool { Probe: func(c fiber.Ctx) bool {
return true return true
}, },
@ -108,7 +108,7 @@ type Config struct {
// initialization and readiness checks // initialization and readiness checks
// //
// Optional. Default: func(c fiber.Ctx) bool { return true } // Optional. Default: func(c fiber.Ctx) bool { return true }
Probe HealthChecker Probe func(fiber.Ctx) bool
} }
``` ```
@ -117,7 +117,7 @@ type Config struct {
The default configuration used by this middleware is defined as follows: The default configuration used by this middleware is defined as follows:
```go ```go
func defaultProbe(fiber.Ctx) bool { return true } func defaultProbe(c fiber.Ctx) bool { return true }
var ConfigDefault = Config{ var ConfigDefault = Config{
Probe: defaultProbe, Probe: defaultProbe,

View File

@ -1564,25 +1564,25 @@ With the new version, each health check endpoint is configured separately, allow
// after // after
// Default liveness endpoint configuration // Default liveness endpoint configuration
app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.New(healthcheck.Config{
Probe: func(c fiber.Ctx) bool { Probe: func(c fiber.Ctx) bool {
return true return true
}, },
})) }))
// Default readiness endpoint configuration // Default readiness endpoint configuration
app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.NewHealthChecker()) app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.New())
// New default startup endpoint configuration // New default startup endpoint configuration
// Default endpoint is /startupz // Default endpoint is /startupz
app.Get(healthcheck.DefaultStartupEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ app.Get(healthcheck.DefaultStartupEndpoint, healthcheck.New(healthcheck.Config{
Probe: func(c fiber.Ctx) bool { Probe: func(c fiber.Ctx) bool {
return serviceA.Ready() && serviceB.Ready() && ... return serviceA.Ready() && serviceB.Ready() && ...
}, },
})) }))
// Custom liveness endpoint configuration // Custom liveness endpoint configuration
app.Get("/live", healthcheck.NewHealthChecker()) app.Get("/live", healthcheck.New())
``` ```
#### Monitor #### Monitor

View File

@ -18,7 +18,7 @@ type Config struct {
// the application is in a state where it can handle requests (e.g., the server is up and running). // the application is in a state where it can handle requests (e.g., the server is up and running).
// //
// Optional. Default: func(c fiber.Ctx) bool { return true } // Optional. Default: func(c fiber.Ctx) bool { return true }
Probe HealthChecker Probe func(fiber.Ctx) bool
} }
const ( const (
@ -27,9 +27,9 @@ const (
DefaultStartupEndpoint = "/startupz" DefaultStartupEndpoint = "/startupz"
) )
func defaultProbe(fiber.Ctx) bool { return true } func defaultProbe(c fiber.Ctx) bool { return true }
func defaultConfigV3(config ...Config) Config { func defaultConfig(config ...Config) Config {
if len(config) < 1 { if len(config) < 1 {
return Config{ return Config{
Probe: defaultProbe, Probe: defaultProbe,

View File

@ -4,11 +4,8 @@ import (
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3"
) )
// HealthChecker defines a function to check liveness or readiness of the application func New(config ...Config) fiber.Handler {
type HealthChecker func(fiber.Ctx) bool cfg := defaultConfig(config...)
func NewHealthChecker(config ...Config) fiber.Handler {
cfg := defaultConfigV3(config...)
return func(c fiber.Ctx) error { return func(c fiber.Ctx) error {
// Don't execute middleware if Next returns true // Don't execute middleware if Next returns true

View File

@ -34,9 +34,9 @@ func Test_HealthCheck_Strict_Routing_Default(t *testing.T) {
StrictRouting: true, StrictRouting: true,
}) })
app.Get(DefaultLivenessEndpoint, NewHealthChecker()) app.Get(DefaultLivenessEndpoint, New())
app.Get(DefaultReadinessEndpoint, NewHealthChecker()) app.Get(DefaultReadinessEndpoint, New())
app.Get(DefaultStartupEndpoint, NewHealthChecker()) app.Get(DefaultStartupEndpoint, New())
shouldGiveOK(t, app, "/readyz") shouldGiveOK(t, app, "/readyz")
shouldGiveOK(t, app, "/livez") shouldGiveOK(t, app, "/livez")
@ -53,9 +53,9 @@ func Test_HealthCheck_Default(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
app.Get(DefaultLivenessEndpoint, NewHealthChecker()) app.Get(DefaultLivenessEndpoint, New())
app.Get(DefaultReadinessEndpoint, NewHealthChecker()) app.Get(DefaultReadinessEndpoint, New())
app.Get(DefaultStartupEndpoint, NewHealthChecker()) app.Get(DefaultStartupEndpoint, New())
shouldGiveOK(t, app, "/readyz") shouldGiveOK(t, app, "/readyz")
shouldGiveOK(t, app, "/livez") shouldGiveOK(t, app, "/livez")
@ -73,12 +73,12 @@ func Test_HealthCheck_Custom(t *testing.T) {
app := fiber.New() app := fiber.New()
c1 := make(chan struct{}, 1) c1 := make(chan struct{}, 1)
app.Get("/live", NewHealthChecker(Config{ app.Get("/live", New(Config{
Probe: func(_ fiber.Ctx) bool { Probe: func(_ fiber.Ctx) bool {
return true return true
}, },
})) }))
app.Get("/ready", NewHealthChecker(Config{ app.Get("/ready", New(Config{
Probe: func(_ fiber.Ctx) bool { Probe: func(_ fiber.Ctx) bool {
select { select {
case <-c1: case <-c1:
@ -88,7 +88,7 @@ func Test_HealthCheck_Custom(t *testing.T) {
} }
}, },
})) }))
app.Get(DefaultStartupEndpoint, NewHealthChecker(Config{ app.Get(DefaultStartupEndpoint, New(Config{
Probe: func(_ fiber.Ctx) bool { Probe: func(_ fiber.Ctx) bool {
return false return false
}, },
@ -123,12 +123,12 @@ func Test_HealthCheck_Custom_Nested(t *testing.T) {
app := fiber.New() app := fiber.New()
c1 := make(chan struct{}, 1) c1 := make(chan struct{}, 1)
app.Get("/probe/live", NewHealthChecker(Config{ app.Get("/probe/live", New(Config{
Probe: func(_ fiber.Ctx) bool { Probe: func(_ fiber.Ctx) bool {
return true return true
}, },
})) }))
app.Get("/probe/ready", NewHealthChecker(Config{ app.Get("/probe/ready", New(Config{
Probe: func(_ fiber.Ctx) bool { Probe: func(_ fiber.Ctx) bool {
select { select {
case <-c1: case <-c1:
@ -164,7 +164,7 @@ func Test_HealthCheck_Next(t *testing.T) {
app := fiber.New() app := fiber.New()
checker := NewHealthChecker(Config{ checker := New(Config{
Next: func(_ fiber.Ctx) bool { Next: func(_ fiber.Ctx) bool {
return true return true
}, },
@ -184,9 +184,9 @@ func Test_HealthCheck_Next(t *testing.T) {
func Benchmark_HealthCheck(b *testing.B) { func Benchmark_HealthCheck(b *testing.B) {
app := fiber.New() app := fiber.New()
app.Get(DefaultLivenessEndpoint, NewHealthChecker()) app.Get(DefaultLivenessEndpoint, New())
app.Get(DefaultReadinessEndpoint, NewHealthChecker()) app.Get(DefaultReadinessEndpoint, New())
app.Get(DefaultStartupEndpoint, NewHealthChecker()) app.Get(DefaultStartupEndpoint, New())
h := app.Handler() h := app.Handler()
fctx := &fasthttp.RequestCtx{} fctx := &fasthttp.RequestCtx{}
@ -206,9 +206,9 @@ func Benchmark_HealthCheck(b *testing.B) {
func Benchmark_HealthCheck_Parallel(b *testing.B) { func Benchmark_HealthCheck_Parallel(b *testing.B) {
app := fiber.New() app := fiber.New()
app.Get(DefaultLivenessEndpoint, NewHealthChecker()) app.Get(DefaultLivenessEndpoint, New())
app.Get(DefaultReadinessEndpoint, NewHealthChecker()) app.Get(DefaultReadinessEndpoint, New())
app.Get(DefaultStartupEndpoint, NewHealthChecker()) app.Get(DefaultStartupEndpoint, New())
h := app.Handler() h := app.Handler()