package api import ( "context" "crypto/tls" "fmt" "loveuer/utodo/pkg/handler" "loveuer/utodo/pkg/logger" "net" "github.com/gofiber/fiber/v3" l3 "github.com/gofiber/fiber/v3/middleware/logger" r3 "github.com/gofiber/fiber/v3/middleware/recover" ) type Option func(*option) type option struct { name string version string address string app *fiber.App tlsConfig *tls.Config } func WithName(name string) Option { return func(o *option) { if name != "" { o.name = name } } } func WithAddress(address string) Option { return func(o *option) { if address != "" { o.address = address } } } func WithApp(app *fiber.App) Option { return func(o *option) { if app != nil { o.app = app } } } func WithVersion(version string) Option { return func(o *option) { if version != "" { o.version = version } } } func WithTLSConfig(tlsConfig *tls.Config) Option { return func(o *option) { if tlsConfig != nil { o.tlsConfig = tlsConfig } } } func Start(ctx context.Context, opts ...Option) (func(context.Context) error, error) { var ( err error fn func(context.Context) error ln net.Listener opt = &option{ name: "utodo", version: "0.0.1", address: ":80", } ) for _, o := range opts { o(opt) } if opt.app == nil { logger.WarnCtx(ctx, "app is nil, use default app!!!") logger.WarnCtx(ctx, "app is nil, use default app!!!") logger.WarnCtx(ctx, "app is nil, use default app!!!") opt.app = fiber.New(fiber.Config{BodyLimit: 1024 * 1024 * 5}) opt.app.Use(l3.New()) opt.app.Use(r3.New()) opt.app.Get("/healthz", handler.Healthz(opt.name, opt.version)) } if opt.tlsConfig != nil { ln, err = tls.Listen("tcp", opt.address, opt.tlsConfig) } else { ln, err = net.Listen("tcp", opt.address) } if err != nil { return nil, err } go func() { if err := opt.app.Listener(ln); err != nil { logger.ErrorCtx(ctx, "service[%s:%s] running failed, err = %v", opt.name, opt.version, err) } }() fn = func(_ctx context.Context) error { logger.WarnCtx(_ctx, "service[%s] shutdown...", opt.name) if err := opt.app.ShutdownWithContext(_ctx); err != nil { return fmt.Errorf("service[%s:%s] shutdown failed, err = %w", opt.name, opt.version, err) } return nil } return fn, nil }