Changelog
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
[Unreleased]
[1.5.0] - 2026-06-14
Added
retrypackage: generic retry with exponential backoff + optional jitter —Do(ctx, fn, opts...)andDoValue[T], withWithAttempts/WithDelay/WithMaxDelay/WithMultiplier/WithJitter/WithRetryIf.inboxpackage: idempotent-consumer dedup —Once(ctx, db, messageID, fn)records a marker and runs fn in one transaction (duplicate IDs skip fn; a failing fn rolls the marker back). The consumer-side complement tooutbox.dbresolverpackage: explicit read/write split over Bun —New(primary, replicas...)withWriter()(primary) andReader()(round-robin replica, primary when none), plusPing/Close.
[1.4.0] - 2026-06-14
Added
pagination:(*CursorPage[T]).LinkHeader(baseURL)builds an RFC 5988Linkheader withrel="next"/rel="prev"from the page cursors.http:WithContextHeader(header, extract)sets a per-request header from the call's context (e.g. propagate a request id or trace correlation downstream).
[1.3.0] - 2026-06-14
Added
cachepackage: a generic in-memory cacheCache[V]with TTL, LRU max-size eviction, and singleflightGetOrLoad. Complementsredis.Remember(remote) for hot data without a network round-trip.ratelimitpackage: a Redis-backed token-bucket limiter (per-key buckets, cost-per-request viaAllow) with a FiberMiddleware(429 +Retry-After+X-RateLimit-*headers).apikeypackage: API-key authentication (distinct from JWTauth) — hash a presented key and resolve its identity + scopes via a pluggableStore(MapStore), withGenerate/Hash, a FiberMiddleware,RequireScope, andFromContext/HasScope.
[1.2.0] - 2026-06-14
Added
health: dependency probesPingRedis,PingHTTP, andPingTCP.health.ReadinessGate+server.RunGracefulWithConfig/server.Config: flip/readyzto not-ready and wait a drain delay before shutting down, so a load balancer stops routing first.server.RunGracefulis unchanged (delegates with the new defaults).http: optional circuit breaker viaWithCircuitBreaker(maxFailures, openTimeout)— rejects calls withErrCircuitOpenwhile a dependency is failing, with a half-open probe after the timeout.redis.Remember: in-process singleflight deduplication so concurrent misses for the same key run the loader once (cache-stampede protection).eventspackage: in-process typed event bus (Subscribe[T]/Publish[T]), synchronous by default with an opt-in async mode (WithAsync). Complementsoutboxfor intra-process fan-out.featureflagpackage: runtime flags (boolean, percentage rollout, per-user/group targeting) via a pluggableProvider—Static,Rules, andRedis— plus a FiberMiddlewareandEnabled(c, flag)helper.auditpackage: structured audit log — aRecorderwrites actor/action/target entries through a pluggableSink(NewBunSink+Migrate+List), with a FiberFromRequesthelper prefilling actor/IP/request-id.
[1.1.0] - 2026-06-13
Fixed
lock:Acquirenow reportsErrNotAcquiredwhen the context is cancelled or times out during an acquisition attempt (previously the raw Redis transport error could leak through, soerrors.Is(err, ErrNotAcquired)was unreliable).
Added
lockpackage: single-instance Redis distributed mutex (TryAcquire/Acquire/Do, owner-onlyRelease/Extend) for single-execution across replicas.- Keyset (cursor) pagination:
parser.KeysetBun modifier with opaque cursors (EncodeCursor/DecodeCursor) andpagination.CursorPage/NewCursorPagewith forward and backward navigation. Complements the existing offset pagination. outboxpackage: transactional outbox (Enqueuewithin a Bun transaction + a backgroundRelaythat publishes pending events at-least-once, withNewRedisPublisherand optional single-relay coordination vialock). Solves the dual-write problem between the database and Redis pub/sub.fibrtestpackage: a test harness for fibr/Fiber apps — a fluent HTTPClientover*fiber.App(Get/Post/Requestbuilder,WithBearer), response assertions (ExpectStatus/JSON/Text), plusNewDB(in-memory SQLite Bun) andToken(JWT minting) helpers.
[1.0.0] - 2026-06-13
First stable release. The public API is now covered by the compatibility guarantee in the README — no breaking changes will land within the v1.x series; anything breaking will go to v2.
No functional changes since v0.6.0. This release marks the API as stable after the v0.6.0 hardening pass (idiomatic-Go cleanup, stricter linters, fuzz tests for the parser surfaces, and the final breaking renames).
[0.6.0] - 2026-06-13
Added
redis: bulk and atomic helpers —MSet/MGet(pipelined),Incr/Decr,SetNX,GetSet.http:PostForm(urlencoded) andPostMultipart(file upload) requests.jobs: option helpersWithRetry/WithPriority/WithProcessIn/WithDeadline(returnasynq.Option, so callers need not import asynq).i18n: CLDR cardinal plural categories (zero/one/two/few/many/other) for en/fr/ru/uk/pl/ar and the no-plural languages; unknown locales use the English rule.Pluralnow resolves<key>.<category>.ws:(*Hub[T]).BackplaneErr()surfaces a failed Redis backplane subscription (the hub still serves local connections).
Changed
- Added
// Packagedoc comments to 16 packages; replacedinterface{}withany. - Stricter golangci-lint set (revive, unconvert, unparam, …) enforced in CI.
Removed
- Breaking:
http.Httprenamed tohttp.HTTPandhttp.HTTPErrortohttp.Error(stutter fixes). Update references accordingly. - Breaking:
middleware.Authremoved — useauth.RequireAuth(adds token revocation and scope checks).
[0.5.0] - 2026-06-11
Added
openapipackage: build an OpenAPI 3.0.3 spec from registered routes and reflected request/response structs (json + validator tags → JSON Schema with$refs, enums, formats, and min/max constraints). Serve it at/openapi.jsonwith a CDN-backed Swagger UI at/docs. Newbootstrap.Options.OpenAPI(plusOpenAPISpecURL/OpenAPIDocsURL) mounts both endpoints, and generated apps expose API docs out of the box (auth routes pre-registered when--auth).wspackage: typed WebSocketHub[T](rooms,Broadcast/ToRoom, per-connection write pump, keepalive ping) on gofiber/contrib/websocket, with an optional Redis backplane (WithRedis) bridging broadcasts across replicas via the existingredispub/sub.ssepackage: Server-Sent Events stream helper (Handler+Stream.Send/SendRaw/Comment/Event) with JSON encoding and multi-line data framing.- Generator: new
fibr new --realtimeflag scaffolds a WebSocket chat (/ws/:room) + SSE counter (/events); backplane auto-enabled whenREDIS_URLis set. i18npackage: dependency-free internationalization — a messageBundleloaded from nested JSON (flattened to dotted keys) with{placeholder}substitution, one/other pluralization (Plural/N), and a fallback locale; a locale-detection middleware (query > cookie >Accept-Language) andT/N/Localerequest helpers. Newbootstrap.Options.I18nmounts the middleware, andfibr new --i18nscaffolds en/id catalogs + a sample localized route.
[0.4.0] - 2026-06-10
Added
bindpackage:Body[T]/Query[T]/Params[T]parse a request intoT, validate it, and on failure write a400(malformed) or422(validation, with per-field errors) response — returningok=falseso handlers stop withreturn nil.jobs.Scheduler: cron-triggered job scheduling (Register/Run/Shutdown/Unregister,WithLocation) on top of asynq. Generated--queueapps gain aschedulersubcommand and a sample daily cleanup cron.uploader.S3Uploader: S3-compatible uploads (AWS S3, MinIO, R2, ...) via minio-go, behind the existingUploaderinterface, withWithKeyPrefix/WithBaseURL. Validation (size, MIME, filename) is now shared withLocalUploader; theOptiontype is unified across both.-
redis.Storage(NewStorage/WithPrefix): afiber.Storageadapter over go-redis, plusbootstrap.Options.RateLimitStorage. Generated apps use a Redis-backed (multi-instance-consistent) rate limiter whenREDIS_URLis set. -
apierrorpackage: typed HTTP errors (BadRequest/Unauthorized/NotFound/Conflict/Internal/...) withWithCode/WithDetails/Wrap, plus a FiberErrorHandler.bootstrapinstalls it by default, so a returned error renders as the JSON envelope. Adds an optionalerrorfield toresponse.Response. Generated auth handlers now return typed errors. -
bootstrap.Options.SecurityHeaders(helmet security response headers) andCompression(gzip/deflate/brotli) opt-in middlewares; generated apps enable both by default. bootstrap.Options.Idempotency+IdempotencyStorage: opt-in idempotency-key middleware (replays the cached response for a repeatedX-Idempotency-Keyon unsafe methods). Generated apps enable it, backed by Redis whenREDIS_URLis set.webhookpackage: HMAC-SHA256Sign/Verify(Stripe-stylet=,v1=with timestamp replay protection) and aMiddlewarethat guards inbound webhook routes (401 on bad signature).redispub/sub:(*Redis).Publishand genericSubscribe[T](background goroutine +Subscription.Close) for cross-instance events like cache invalidation and broadcasts.
Changed
- Generated handlers (module CRUD + auth register/login/refresh) now use
bind.Bodyand validate input via struct tags. Missing required fields now return422instead of400.
[0.3.0] - 2026-06-08
Changed
- BREAKING: renamed the project from
fiber-helperstofibr. The module path is nowgithub.com/rahmadafandi/fibr; update all imports. The repository moved togithub.com/rahmadafandi/fibr(the old URL redirects). - BREAKING: the generator CLI is now
fibrwith subcommands. Scaffold a project withfibr new <name>(wascreate-fiber-app <name>);fibr add module <name>is unchanged. Install withgo install github.com/rahmadafandi/fibr/cmd/fibr@latest. Release binaries are namedfibr.
[0.2.2] - 2026-06-08
Added
- Developer tooling: root
Makefile(build/test/cover/lint/vet/vuln/tidy/check),lefthook.ymlgit hooks (gofmt + golangci-lint on commit, tests on push). - CI:
govulncheckvulnerability scan job; test coverage profile uploaded to Codecov;examplesbuild/vet job. - Documentation: runnable godoc
Examplefunctions forpagination,jwt,validator,parser,response, andslug(rendered on pkg.go.dev). examples/: runnable demo apps forauth,mailer, andqueue, plus a README index.
[0.2.1] - 2026-06-08
Changed
go.mod: retract pre-release tags[v0.1.0, v0.1.13]. They predate the project stabilizing and point at commits removed by a history rewrite; they were never intended as supported releases.go getand pkg.go.dev now steer users to v0.2.0+.
[0.2.0] - 2026-06-07
Added
metricspackage: Prometheus request metrics middleware +/metricshandler (http_requests_total/http_request_duration_secondswith route-template labels; default Go/process collectors). Opt-in viabootstrap.Options.Metrics; generated apps toggle it withMETRICS_ENABLED.tracingpackage: OpenTelemetry tracer setup (Setupwith OTLP/HTTP exporter, global provider + W3C propagator,WithServiceName/WithSampler). Opt-in viabootstrap.Options.Tracing(otelfiber spans) +Options.Cleanup; request logs gaintrace_id/span_id; generated apps toggle withTRACING_ENABLED.database.WithTracing(): installs Bun'sbunotelOpenTelemetry query hook so SQL queries are recorded as spans. Generated apps enable it automatically whenTRACING_ENABLEDis set.rediscache helpers:Delete(variadic),Exists,Expire, andTTLon*Redisfor invalidating and inspecting cached entries.jobspackage: typed asynq queue wrapper (Client.Enqueue, genericHandle[T], workerServerwithRun/ProcessTask) and a mountable asynqmon monitoring handler (MonitoringHandler).bootstrap.Options.Asynqmon(AsynqmonMount): opt-in mount for a monitoring UIhttp.Handlerwith optional guard middleware (asynqmon dependency stays out ofbootstrap).create-fiber-app --queue: scaffolds a sample job, aworkersubcommand, the asynqmon UI mount, andREDIS_URL/QUEUE_CONCURRENCY/ASYNQMON_PATHconfig (both ddd and layered layouts). EmptyREDIS_URLdisables the queue with a warning (fail-soft).mailerpackage: pluggableSender(SMTPSendervia go-mail,LogSenderdev fallback,MemorySenderfor tests),Message, and aRenderHTML+text template helper.Newfalls back toLogSenderwhen no SMTP host is set.create-fiber-app --mailer: scaffolds SMTP config/env, a/email/testroute, and real send wiring for the welcome job (--queue, async via anemail:sendjob) and team invitation email (--auth-with-team). Both layouts.authpackage: bcryptHash/Compare, JWT bearer middleware (RequireAuth/Optional), claims accessors (Claims/Subject), and scope checks (RequireScope/HasScope/Scopes).authrefresh tokens + revocation:Issuer(Issue/Refresh/Logout) mints rotating access+refresh JWT pairs (TokenPair) with family-based reuse detection;TokenStoreinterface withRedisStoreandMemoryStoreimpls;WithBlocklistmakesRequireAuth/Optionalreject revoked tokens byjti(refresh tokens are also rejected for API access).create-fiber-app --auth: scaffolds an auth module (Account, register/login/me- scope-gated route, accounts migration) and generates a random
JWT_SECRET. Login returns an access+refreshTokenPair; adds/auth/refreshand/auth/logout; wires a redis-backed token store whenREDIS_URLis set, falling back to an in-memory store otherwise. authteam/workspace helpers:ActiveTeam,TeamRole,RequireTeam, andRequireRoleread the active team carried in the JWT (team/roleclaims); theIssuernow propagatesteam/rolethrough refresh.create-fiber-app --auth-with-team(implies--auth): multi-tenant scaffold where one account belongs to many teams via memberships, each team role maps to a permission set (carried as the active team'sscopes). Adds Team/Membership entities + migrations,POST /auth/switch-team,GET /teams,POST /teams,POST /teams/:id/members(gated bymember:manage), team-aware/me, and ateam:manageexample route; register auto-creates a personal team.create-fiber-app --auth-with-teamdynamic roles: each team owns its roles in the database (roles+role_permissionstables, seeded with owner/admin/member/viewer on team creation) instead of a static code map. Permissions are drawn from a fixed code catalog (GET /permissions) and resolved into the JWT at login/switch-team. Adds role management —GET/POST /teams/:id/roles,PUT/DELETE /teams/:id/roles/:name(owner- protected, in-use 409), andPUT /teams/:id/members(change a member's role) — all gated byrole:manage/member:manageand scoped to the active team.migratepackage:bun/migratewrapper (Up/Down/Status/Create) plus a ready cobraNewCommand(up/down/status/create).- Generated projects are now a single cobra binary with
serve+migratesubcommands and aninternal/migrations/package;--sampleandadd moduleemitcreate tablemigrations. bootstrap.Options.AutoMigrateto run moduleMigrateat startup (dev).bootstrap.Moduleinterface andApp.Mountfor self-wiring feature modules, with optionalMigratorandHealthCheckercapabilities.health.RegisterProvider/RegisterProviderAtfor live readiness checks.create-fiber-app add module <name>subcommand scaffolding a complete feature module for the detected layout (ddd/layered).database:NewBunopens a Bun ORM connection with automatic Postgres/SQLite dialect detection from the DSN; pool options (WithMaxOpenConns,WithMaxIdleConns,WithConnMaxLifetime,WithPingTimeout,WithoutPing).health:Register/RegisterAtmount/livez(liveness) and/readyz(readiness) endpoints that run named checks concurrently;/readyzapplies an overall deadline so a stuck check cannot hang the server.PingBunandCheckhelpers provided.server:RunGracefulstarts a Fiber app and blocks until SIGINT/SIGTERM, then shuts the server down cleanly and calls optional cleanup hooks.bootstrap:New(Options)wires recover, request-id, structured logging, optional CORS, optional rate limiting (health probes are exempt), optional DB health checks, and graceful shutdown in a single call.App.Run(addr)replacesfiber.App.Listen.config:default:"..."andrequired:"true"struct tags; extended type support (time.Duration, float, bool, integer with per-kind overflow detection, comma-separated[]string); combined error reporting across all fields.http: Context-aware JSON client built on fasthttp. All methods (Get,Post,Put,Patch,Delete) acceptcontext.Contextand return(statusCode int, err error).WithRetryretries only on 5xx;WithTimeout,WithHeaderoptions;FireAndForgetfor background non-blocking calls;HTTPErrortype for status-code errors.redis: GenericRemembercache-aside helper that returns a cached value or calls a loader on miss.ParseRedisOptionsparses a Redis URL into*redis.Optionsand returns an error on bad input.validator:Registerfor custom validation rules; error messages use JSON field names and include the failing value; handles non-struct input without panicking.jwt:GenerateTokenWithExpiryfor generating tokens with an explicit expiry duration.uploader:WithMaxSizeandWithAllowedMimeoptions forNewLocalUploader; filenames are sanitized and permissions are tightened; partial files are removed on write error.middleware:X-Request-IDresponse header added by the request-id middleware so callers can correlate responses.context:SetLocalandGetLocaltyped helpers replace the formerCustomContext.pagination:paginationpackage extracted to manage page/limit logic independently.
Changed
bootstrap.App.Mountruns a module'sMigrateonly when the app was built withAutoMigrate: true(previously always). Schema is owned by migrations by default.create-fiber-app --samplenow generates the sampleuserfeature as abootstrap.Modulemounted viaapp.Mount(previously hand-wired in main.go).- ORM migration: GORM removed; Bun is now the ORM throughout the library.
parserpagination scopes andslug.Generate(nowslug.Generate(ctx, db, table, text) (string, error)) migrated accordingly. config.LoadConfig: Signature changed from a generic return (LoadConfig[T]() (T, error)) to pointer-out (LoadConfig(out any) error), matching idiomatic Go.httpmethods: All request methods now accept a leadingcontext.Contextargument and return(int, error)instead of a plain error.commonpackage removed: Functionality split into theresponseandloggerpackages.
Removed
commonpackage: Replaced by dedicatedresponseandloggerpackages.parser.ParseBody/ParseQuery/ParseParams: Removed generic parse helpers; use Fiber's built-inc.BodyParser,c.QueryParser, andc.ParamsParserdirectly.redis.GormResult: Removed broken GORM-coupled helper; useRememberinstead.
Fixed
pagination: Guard against divide-by-zero whenlimitis zero; clamp page number to a valid range.parser: Corrected ILIKE pattern construction; added SQL-injection guard on the sort column expression.uploader: Path-traversal protection on uploaded filenames; partial file is cleaned up on write error; file permissions tightened.validator: No longer panics on non-struct input.config: Per-kind numeric overflow detection; errors from all fields are combined and reported together.slug: Uniqueness retry loop is now capped to prevent an infinite spin.redis:ParseRedisOptionsreturns an error instead ofnilon a bad URL.server: Signal-notify goroutine and exit bridge goroutine are cleaned up correctly on return.database: Malformed DSN schemes are rejected with an error instead of being silently treated as SQLite.http:FireAndForgetdetaches from the caller's context so cancellation does not abort background requests; retry backoff is context-aware.