diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 3ba8a23..a20fb5f 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -1,13 +1,27 @@ name: Node.js CI +# Triggers: +# - push to main → publish_stage publishes :stage (internal) +# - push tag v* → release_package publishes :latest + :vX.Y.Z +# - PR to main/development → build job only (no publish) +# - workflow_dispatch → manual button to refresh :stage on demand +# +# Stage deploys (gofr-dev/gofr's website-stage.yml) pull :stage, so +# every merge to website main automatically refreshes what stage shows. +# Prod deploys (website-prod.yml) build inline from this source rather +# than pulling :latest, so prod is always fresh on every framework +# release tag regardless of when the website was last tagged. on: push: + branches: + - main tags: - 'v*' pull_request: branches: - main - development + workflow_dispatch: jobs: build: @@ -24,6 +38,62 @@ jobs: yarn install yarn build + # Internal :stage artifact. Published on every push to main + via + # workflow_dispatch. Each run refreshes data so :stage bakes in + # current GoFr release / roadmap / contributor state. Stage deploys + # in gofr-dev/gofr pull this image — pulling is cheaper than + # rebuilding the website from source on every push to gofr's + # development branch. + publish_stage: + if: | + (github.event_name == 'push' && github.ref == 'refs/heads/main') || + github.event_name == 'workflow_dispatch' + needs: build + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Use Node.js 18.x + uses: actions/setup-node@v4 + with: + node-version: 18.x + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Refresh data from GitHub (snapshot fallback on failure) + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: yarn refresh-data + continue-on-error: true + + - name: Log in to the Container registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Docker image (:stage) + uses: docker/build-push-action@v4 + with: + push: true + context: . + file: Dockerfile + tags: ghcr.io/gofr-dev/website:stage + + # Public :latest artifact. Published on tag v* push as a versioned + # release + the rolling :latest pointer. Prod deploys do NOT pull + # this — they build inline — but it's kept as an external artifact + # and a rollback target. release_package: if: ${{ startsWith(github.ref, 'refs/tags/v')}} needs: build @@ -36,6 +106,39 @@ jobs: steps: - name: Checkout Code uses: actions/checkout@v4 + # Full history is needed by utils/generate-doc-mtimes.mjs which + # reads `git log` per source file to compute the visible + # "Last updated" byline. A shallow clone would give every doc + # the same boot timestamp. + with: + fetch-depth: 0 + + - name: Use Node.js 18.x + uses: actions/setup-node@v4 + with: + node-version: 18.x + + - name: Install dependencies + run: yarn install --frozen-lockfile + + # Pull fresh data from GitHub at deploy time — releases, roadmap + # milestones, team profiles + contributor list, and per-doc git + # mtimes. The fetch scripts each have a snapshot fallback: on a + # rate-limited or transient failure they keep the previously- + # committed JSON rather than emitting an empty file. + # + # `continue-on-error: true` makes this step non-blocking — even + # in the worst case (every API call failed) the build proceeds + # with the committed snapshots, never an empty website. + # + # Auth uses the workflow's built-in GITHUB_TOKEN (1000 req/hr), + # which is enough for our ~150-request refresh and avoids the + # 60/hr unauthenticated cliff. + - name: Refresh data from GitHub (snapshot fallback on failure) + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: yarn refresh-data + continue-on-error: true - name: Log in to the Container registry uses: docker/login-action@v1 @@ -47,7 +150,7 @@ jobs: - name: Extract Release Tag run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - - name: Build and push Docker image + - name: Build and push Docker image (:latest + :v*) uses: docker/build-push-action@v4 with: push: true diff --git a/Dockerfile b/Dockerfile index 9aaf7f8..fff000c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ WORKDIR /app COPY src src/. COPY utils utils/. +COPY public public/. COPY jsconfig.json . COPY next.config.mjs . COPY package.json . diff --git a/next.config.mjs b/next.config.mjs index 85fa37c..6ff04dc 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -6,14 +6,82 @@ import withSearch from './src/markdoc/search.mjs' /** @type {import('next').NextConfig} */ const nextConfig = { output: 'export', + // `output: 'export'` disables Next's image optimisation API + // (/_next/image). Without `images.unoptimized = true`, every + // tag emits a /_next/image?url=... src that 404s in + // production and renders as a browser broken-image icon. Setting + // it once here means we don't need to remember `unoptimized` on + // every usage. PNG/JPG sizes are managed at the source. + images: { unoptimized: true }, pageExtensions: ['js', 'jsx', 'md', 'ts', 'tsx'], webpack(config) { config.module.rules.unshift({ test: /\.md$/, use: [ createLoader(function (source) { + // Inject metadataBase so Open Graph and Twitter image URLs + // resolve to gofr.dev in production builds. The frontmatter + // `nextjs.metadata` block layers title/description on top. + // + // We also auto-derive page-level `openGraph` and `twitter` + // title/description from the frontmatter's top-level title and + // description. Without this, every Markdoc page inherits the + // root layout's openGraph.title / twitter.title — meaning every + // social share preview shows the home page's card. The author of + // a doc can still override by setting `nextjs.metadata.openGraph` + // or `nextjs.metadata.twitter` explicitly in frontmatter. + // + // Derive the route from the resource path (e.g. + // `/src/app/docs/guides/deploying-to-kubernetes/page.md` → + // `/docs/guides/deploying-to-kubernetes`). We inject this as + // `alternates.canonical` so every Markdoc page emits a unique + // . Next's metadata API does NOT + // auto-derive canonical from metadataBase + pathname; it must + // be set explicitly. The page can override by providing + // `nextjs.metadata.alternates.canonical` in frontmatter. + const resourcePath = (this.resourcePath || '').replace(/\\/g, '/') + const appIdx = resourcePath.indexOf('/src/app/') + let __canonical = '/' + if (appIdx !== -1) { + const rel = resourcePath.slice(appIdx + '/src/app/'.length) + // Strip trailing /page.md + const stripped = rel.replace(/\/page\.md$/, '') + __canonical = '/' + stripped + if (__canonical === '/') __canonical = '/' + } return ( - source + '\nexport const metadata = frontmatter.nextjs?.metadata;' + source + + ` +const __pageMeta = frontmatter.nextjs?.metadata || {}; +const __pageTitle = typeof __pageMeta.title === 'string' ? __pageMeta.title : undefined; +const __pageDesc = typeof __pageMeta.description === 'string' ? __pageMeta.description : undefined; +const __og = { + ...(__pageTitle ? { title: __pageTitle } : {}), + ...(__pageDesc ? { description: __pageDesc } : {}), + ...(__pageMeta.openGraph || {}), +}; +const __tw = { + ...(__pageTitle ? { title: __pageTitle } : {}), + ...(__pageDesc ? { description: __pageDesc } : {}), + ...(__pageMeta.twitter || {}), +}; +const __derivedCanonical = ${JSON.stringify(__canonical)}; +const __alternates = { + canonical: __derivedCanonical, + ...(__pageMeta.alternates || {}), +}; +// Only emit openGraph / twitter when the page actually carries +// per-page values. If we always emitted an object, Next's metadata +// merge would replace the parent layout's openGraph wholesale and +// strip its title/description for pages with no frontmatter. +export const metadata = { + metadataBase: new URL("https://gofr.dev"), + ...__pageMeta, + alternates: __alternates, + ...(Object.keys(__og).length ? { openGraph: { type: 'article', ...__og } } : {}), + ...(Object.keys(__tw).length ? { twitter: { card: 'summary_large_image', ...__tw } } : {}), +}; +` ) }), ], diff --git a/package-lock.json b/package-lock.json index af7ca40..dc31266 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "copy-to-clipboard": "^3.3.3", "fast-glob": "^3.3.3", "flexsearch": "^0.7.31", - "js-yaml": "^4.1.0", + "js-yaml": "^4.1.1", "next": "13.4.16", "next-themes": "^0.2.1", "prism-react-renderer": "^2.0.6", @@ -60,7 +60,6 @@ "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.4.0.tgz", "integrity": "sha512-N0blWT/C0KOZ/OJ9GXBX66odJZlrYjMj3M+01y8ob1mjBFnBaBo7gOCyHBDQy60+H4pJXp3pSGlJOqJIueBH+A==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -108,7 +107,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.38.0.tgz", "integrity": "sha512-15d6zv8vtj2l9pnnp/EH7Rhq3/snCCHRz56NnX6xIUPrbJl5gCsIYXAz8C2IEkwOpoDb0r5G6ArY2gKdVMNezw==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -124,7 +122,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.38.0.tgz", "integrity": "sha512-jJIbYAhYvTG3+gEAP5Q5Dp6PFJfUR+atz5rsqm5KjAKK+faLFdHJbM2IbOo0xdyGd+SH259MzfQKLJ9mZZ27dQ==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -140,7 +137,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.38.0.tgz", "integrity": "sha512-aMCXzVPGJTeQnVU3Sdf30TfMN2+QyWcjfPTCCHyqVVgjPipb6RnK40aISGoO+rlYjh9LunDsNVFLwv+JEIF8bQ==", "license": "MIT", - "peer": true, "engines": { "node": ">= 14.0.0" } @@ -150,7 +146,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.38.0.tgz", "integrity": "sha512-4c3FbpMiJX+VcaAj0rYaQdTLS/CkrdOn4hW+5y1plPov7KC7iSHai/VBbirmHuAfW1hVPCIh1w/4erKKTKuo+Q==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -166,7 +161,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.38.0.tgz", "integrity": "sha512-FzLs6c8TBL4FSgNfnH2NL7O33ktecGiaKO4ZFG51QYORUzD5d6YwB9UBteaIYu/sgFoEdY57diYU4vyBH8R6iA==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -182,7 +176,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.38.0.tgz", "integrity": "sha512-7apiahlgZLvOqrh0+hAYAp/UWjqz6AfSJrCwnsoQNzgIT09dLSPIKREelkuQeUrKy38vHWWpSQE3M0zWSp/YrA==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -214,7 +207,6 @@ "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.38.0.tgz", "integrity": "sha512-qGSUGgceJHGyJLZ06bFLwVe2Tpf9KwabmoBjFvFscVmMmU5scKya6voCYd9bdX7V0Xy1qya9MGbmTm4zlLuveQ==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -230,7 +222,6 @@ "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.38.0.tgz", "integrity": "sha512-VnCtAUcHirvv/dDHg9jK1Z5oo4QOC5FKDxe40x8qloru2qDcjueT34jiAsB0gRos3VWf9v4iPSYTqMIFOcADpQ==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -246,7 +237,6 @@ "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.38.0.tgz", "integrity": "sha512-fqgeU9GqxQorFUeGP4et1MyY28ccf9PCeciHwDPSbPYYiTqBItHdUIiytsNpjC5Dnc0RWtuXWCltLwSw9wN/bQ==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0", "@algolia/requester-browser-xhr": "5.38.0", @@ -262,7 +252,6 @@ "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.38.0.tgz", "integrity": "sha512-nAUKbv4YQIXbpPi02AQvSPisD5FDDbT8XeYSh9HFoYP0Z3IpBLLDg7R4ahPvzd7gGsVKgEbXzRPWESXSji5yIg==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0" }, @@ -275,7 +264,6 @@ "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.38.0.tgz", "integrity": "sha512-bkuAHaadC6OxJd3SVyQQnU1oJ9G/zdCqua7fwr1tJDrA/v7KzeS5np4/m6BuRUpTgVgFZHSewGnMcgj9DLBoaQ==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0" }, @@ -288,7 +276,6 @@ "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.38.0.tgz", "integrity": "sha512-yHDKZTnMPR3/4bY0CVC1/uRnnbAaJ+pctRuX7G/HflBkKOrnUBDEGtQQHzEfMz2FHZ/tbCL+Q9r6mvwTSGp8nw==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.38.0" }, @@ -579,6 +566,7 @@ "version": "11.11.4", "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", @@ -627,6 +615,7 @@ "version": "11.11.5", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz", "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", @@ -857,6 +846,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/@markdoc/markdoc/-/markdoc-0.3.0.tgz", "integrity": "sha512-QWCF8krIIw52ulflfnoff0yG1eKl9CCGA3KAiOjHyYtHNzSEouFh8lO52nAaO3qV2Ctj1GTB8TTb2rTfvISQfA==", + "peer": true, "engines": { "node": ">=14.7.0" }, @@ -930,6 +920,7 @@ "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz", "integrity": "sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/core-downloads-tracker": "^5.18.0", @@ -1505,6 +1496,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1655,6 +1647,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2123,6 +2116,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001517", "electron-to-chromium": "^1.4.477", @@ -2898,6 +2892,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", @@ -3049,6 +3044,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", @@ -4394,9 +4390,10 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -4697,6 +4694,7 @@ "resolved": "https://registry.npmjs.org/next/-/next-13.4.16.tgz", "integrity": "sha512-1xaA/5DrfpPu0eV31Iro7JfPeqO8uxQWb1zYNTe+KDKdzqkAGapLcDYHMLNKXKB7lHjZ7LfKUOf9dyuzcibrhA==", "license": "MIT", + "peer": true, "dependencies": { "@next/env": "13.4.16", "@swc/helpers": "0.5.1", @@ -5157,6 +5155,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -5323,6 +5322,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", "dev": true, + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -5512,6 +5512,7 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -5523,6 +5524,7 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -6405,6 +6407,7 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "license": "MIT", + "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", diff --git a/package.json b/package.json index 29fb41a..6eb0e9f 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,11 @@ "private": true, "scripts": { "dev": "next dev", + "prebuild": "node utils/fetch-github-stars.mjs && node utils/generate-changelog-rss.mjs && node utils/generate-llms-full.mjs", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "refresh-data": "node utils/fetch-releases.mjs && node utils/fetch-roadmap.mjs && node utils/fetch-team.mjs && node utils/fetch-github-stars.mjs && node utils/generate-doc-mtimes.mjs && node utils/generate-changelog-rss.mjs && node utils/generate-llms-full.mjs" }, "browserslist": "defaults, not ie <= 11", "dependencies": { diff --git a/public/.well-known/security.txt b/public/.well-known/security.txt new file mode 100644 index 0000000..d186cb4 --- /dev/null +++ b/public/.well-known/security.txt @@ -0,0 +1,7 @@ +# Industry-standard discoverable security contact (RFC 9116). +# Reachable at https://gofr.dev/.well-known/security.txt +Contact: mailto:connect@gofr.dev +Contact: https://github.com/gofr-dev/gofr/security/advisories/new +Preferred-Languages: en +Canonical: https://gofr.dev/.well-known/security.txt +Policy: https://github.com/gofr-dev/gofr/blob/main/SECURITY.md diff --git a/public/AGENTS.md b/public/AGENTS.md new file mode 100644 index 0000000..0dcedcc --- /dev/null +++ b/public/AGENTS.md @@ -0,0 +1,101 @@ +# GoFr — guide for AI coding assistants + +For Claude Code, Cursor, Aider, Codex, etc. Hand +[https://gofr.dev/AGENTS.md](https://gofr.dev/AGENTS.md) to your assistant +when working on a GoFr project. It points at the specific docs you'll +actually need rather than inlining everything. + +GoFr is an opinionated Go framework for microservices. Apache 2.0. +Requires Go 1.24+. Repo: . + +## Core rules an assistant must know + +1. **One handler signature** for HTTP / gRPC / GraphQL / WebSocket / SSE / cron / CLI: + `func(c *gofr.Context) (any, error)`. Return value → `{"data": ...}`. Return error → error response. +2. **Path params use `{name}`**, not `:name`. `app.GET("/users/{id}", h)`. +3. **`c.PathParam("id")`** for path; **`c.Param("q")`** for query; **`c.Bind(&v)`** for body. +4. **Don't manually wire OpenTelemetry, Prometheus, or structured logging.** `gofr.New()` does it. +5. **Pass `*gofr.Context`** (not `context.Background()`) to every downstream call so trace propagation and cancellation work. +6. **Configuration comes from `configs/.env`** via `c.Config.Get(key)`. No hardcoded ports / hosts / secrets. +7. **No ORM bundled.** Use plain SQL via `c.SQL`, or pair with `sqlc`/`gorm` yourself. +8. **Middleware is standard `net/http`**: `func(http.Handler) http.Handler`, registered with `app.UseMiddleware(...)`. +9. **Health is auto-exposed** at `/.well-known/health` and `/.well-known/alive`. Don't hand-roll `/healthz`. +10. **Don't `panic()` for control flow.** Return errors. + +## Minimal app + +```go +package main + +import "gofr.dev/pkg/gofr" + +func main() { + app := gofr.New() + app.GET("/hello", func(c *gofr.Context) (any, error) { + return "Hello, world", nil + }) + app.Run() +} +``` + +## Migrations (schema + seed data, versioned) + +GoFr has a built-in migration runner — use it instead of `golang-migrate` / `goose`. Works for SQL, Redis, Mongo, Cassandra, ClickHouse, DGraph, SurrealDB. + +**Before writing a migration, fetch the full reference:** . Runnable shape: . + +Five rules to keep in your head so you don't have to re-fetch on every change: + +1. Files live in `migrations/_.go`. Versions are `int64`, monotonic. Use `date +%s` for new ones. +2. `migrations/all.go` exports `All() map[int64]migration.Migrate`. Wire with `a.Migrate(migrations.All())` once in `main.go`. +3. Each migration is `migration.Migrate{ UP: func(d migration.Datasource) error { ... } }`. Inside `UP`, act on `d.SQL`, `d.Redis`, `d.MongoDB`, `d.Cassandra`, `d.Clickhouse`, `d.DGraph`, `d.SurrealDB`, `d.Logger`. +4. Each migration runs **exactly once** per environment — don't add idempotent guards. There is **no down migration**; rollback = new forward migration. +5. One purpose per file. Don't combine "create table + backfill + drop column" in one `UP`. + +## Where to look (fetch only what you need) + +Each link is a self-contained doc page. Fetch lazily. + +- Quick start: +- Configuration: +- Routing + REST handlers: +- Context reference (the central abstraction): +- Configs reference (every env var): +- Testing patterns + mocks: +- Observability (auto-wired): +- Custom OTel spans: +- Custom Prometheus metrics: +- Datasources index (MySQL, Postgres, Mongo, Redis, Cassandra, ClickHouse, etc.): +- Pub/Sub (Kafka, NATS, GCP, MQTT, SQS, Azure): +- gRPC: +- GraphQL: +- WebSockets: +- Cron: +- Service-to-service HTTP w/ circuit breaker: +- Auth (Basic / API key / OAuth-JWT): +- RBAC (config-driven): +- Migrations (SQL + NoSQL, versioned): +- File storage (local / S3 / GCS / Azure / FTP / SFTP): +- Startup hooks: +- Errors: +- Custom DB drivers: + +## Migrating to GoFr + +Each migration page has the full mapping table for that source framework — fetch only the one that matches: + +- From Gin: +- From Fiber: +- From Echo: handler shape similar to Gin; see +- From Chi: see +- From Express (Node.js): +- From Flask (Python): +- From Spring Boot (Java): + +## Other entry points + +- Examples (runnable projects): +- Full docs index: +- Concatenated full docs (one plaintext file): +- Curated link index: +- Changelog: diff --git a/public/changelog.xml b/public/changelog.xml new file mode 100644 index 0000000..77cedbe --- /dev/null +++ b/public/changelog.xml @@ -0,0 +1,2500 @@ + + + + GoFr Releases + https://gofr.dev/changelog + + Release notes for GoFr — an opinionated Go framework for production microservices. + en-us + Fri, 01 May 2026 15:50:13 GMT + + GoFr v1.56.4 + https://github.com/gofr-dev/gofr/releases/tag/v1.56.4 + v1.56.4 + Wed, 29 Apr 2026 16:16:02 GMT + + + + GoFr v1.56.3 + https://github.com/gofr-dev/gofr/releases/tag/v1.56.3 + v1.56.3 + Tue, 21 Apr 2026 12:29:25 GMT + + + + GoFr v1.56.2 + https://github.com/gofr-dev/gofr/releases/tag/v1.56.2 + v1.56.2 + Tue, 21 Apr 2026 11:35:07 GMT + + + + GoFr v1.56.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.56.1 + v1.56.1 + Thu, 09 Apr 2026 15:11:19 GMT + + + + GoFr v1.56.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.56.0 + v1.56.0 + Tue, 07 Apr 2026 11:57:02 GMT + + + + GoFr v1.55.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.55.0 + v1.55.0 + Sat, 14 Mar 2026 20:39:44 GMT + + + + GoFr v1.54.6 + https://github.com/gofr-dev/gofr/releases/tag/v1.54.6 + v1.54.6 + Wed, 11 Mar 2026 06:17:01 GMT + + + + GoFr v1.54.5 + https://github.com/gofr-dev/gofr/releases/tag/v1.54.5 + v1.54.5 + Fri, 27 Feb 2026 13:32:05 GMT + + + + GoFr v1.54.4 + https://github.com/gofr-dev/gofr/releases/tag/v1.54.4 + v1.54.4 + Sat, 21 Feb 2026 12:45:31 GMT + + + + GoFr v1.54.3 + https://github.com/gofr-dev/gofr/releases/tag/v1.54.3 + v1.54.3 + Fri, 06 Feb 2026 11:20:14 GMT + + + + GoFr v1.54.2 + https://github.com/gofr-dev/gofr/releases/tag/v1.54.2 + v1.54.2 + Sat, 31 Jan 2026 13:45:05 GMT + + + + GoFr v1.54.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.54.1 + v1.54.1 + Tue, 27 Jan 2026 05:43:56 GMT + + + + GoFr v1.54.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.54.0 + v1.54.0 + Sun, 18 Jan 2026 07:02:33 GMT + + + + GoFr v1.53.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.53.0 + v1.53.0 + Sat, 10 Jan 2026 10:03:16 GMT + + + + GoFr v1.52.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.52.0 + v1.52.0 + Fri, 02 Jan 2026 13:45:04 GMT + + + + GoFr v1.51.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.51.0 + v1.51.0 + Sat, 27 Dec 2025 10:02:47 GMT + + + + GoFr v1.50.2 + https://github.com/gofr-dev/gofr/releases/tag/v1.50.2 + v1.50.2 + Sun, 21 Dec 2025 17:05:13 GMT + + + + GoFr v1.50.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.50.1 + v1.50.1 + Sun, 14 Dec 2025 13:55:15 GMT + + + + GoFr v1.50.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.50.0 + v1.50.0 + Sat, 06 Dec 2025 07:16:16 GMT + + + + GoFr v1.49.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.49.0 + v1.49.0 + Fri, 28 Nov 2025 16:14:37 GMT + Hello`) + return response.XML{Content: content}, nil +}) +``` + +**XML Output** + +```xml +Hello +``` + +## 📦 Improvements + +🔹 **Responder Improvements** + +* Special response types (`Raw`, `File`, `Template`, `XML`, `Redirect`) now follow a unified handling flow +* Avoids incorrect `206 Partial Content` responses +* Ensures default JSON `Content-Type` + +🔹 **DBResolver Pooling Controls** + +Replica pools now scale relative to primary pools. Defaults: + +* Primary: `DB_MAX_IDLE_CONNECTION=2` → Replicas default to `8` +* Primary: `DB_MAX_OPEN_CONNECTION=20` → Replicas default to `40` + +Optional overrides: + +```env +DB_REPLICA_MAX_IDLE_CAP=100 +DB_REPLICA_MIN_IDLE=5 +DB_REPLICA_DEFAULT_IDLE=15 +DB_REPLICA_MAX_OPEN_CAP=500 +DB_REPLICA_MIN_OPEN=20 +DB_REPLICA_DEFAULT_OPEN=150 +``` + +## 🐛 Bug Fixes & Small Changes + +🔹 **Authentication Timing Attack Protection** + +* API Key and Basic Auth now use consistent time comparisons + + +Refer : **GoFr Official Documentation** +[https://gofr.dev/docs](https://gofr.dev/docs)]]> + + + GoFr v1.48.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.48.0 + v1.48.0 + Fri, 21 Nov 2025 17:36:33 GMT + + + + GoFr v1.47.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.47.1 + v1.47.1 + Tue, 18 Nov 2025 11:46:54 GMT + + + + GoFr v1.47.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.47.0 + v1.47.0 + Fri, 07 Nov 2025 16:56:09 GMT + + + + GoFr v1.46.3 + https://github.com/gofr-dev/gofr/releases/tag/v1.46.3 + v1.46.3 + Fri, 17 Oct 2025 14:17:15 GMT + + + + GoFr v1.46.2 + https://github.com/gofr-dev/gofr/releases/tag/v1.46.2 + v1.46.2 + Fri, 10 Oct 2025 14:25:33 GMT + + + + GoFr v1.46.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.46.1 + v1.46.1 + Tue, 07 Oct 2025 06:25:18 GMT + + + + GoFr v1.46.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.46.0 + v1.46.0 + Fri, 26 Sep 2025 17:10:55 GMT + + + + GoFr v1.45.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.45.0 + v1.45.0 + Fri, 12 Sep 2025 14:01:09 GMT + + + + GoFr v1.44.2 + https://github.com/gofr-dev/gofr/releases/tag/v1.44.2 + v1.44.2 + Mon, 08 Sep 2025 14:14:25 GMT + + + + GoFr v1.44.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.44.1 + v1.44.1 + Mon, 01 Sep 2025 11:00:58 GMT + + + + GoFr v1.44.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.44.0 + v1.44.0 + Thu, 21 Aug 2025 12:40:56 GMT + + + + GoFr v1.43.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.43.0 + v1.43.0 + Tue, 05 Aug 2025 16:05:43 GMT + + + + GoFr v1.42.5 + https://github.com/gofr-dev/gofr/releases/tag/v1.42.5 + v1.42.5 + Fri, 01 Aug 2025 11:01:15 GMT + + + + GoFr v1.42.4 + https://github.com/gofr-dev/gofr/releases/tag/v1.42.4 + v1.42.4 + Fri, 25 Jul 2025 14:19:51 GMT + + + + GoFr v1.42.3 + https://github.com/gofr-dev/gofr/releases/tag/v1.42.3 + v1.42.3 + Wed, 09 Jul 2025 07:29:40 GMT + + + + GoFr v1.42.2 + https://github.com/gofr-dev/gofr/releases/tag/v1.42.2 + v1.42.2 + Fri, 04 Jul 2025 13:59:35 GMT + + + + GoFr v1.42.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.42.1 + v1.42.1 + Fri, 27 Jun 2025 12:42:48 GMT + + + + GoFr v1.42.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.42.0 + v1.42.0 + Fri, 20 Jun 2025 04:50:59 GMT + + + + GoFr v1.41.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.41.0 + v1.41.0 + Thu, 12 Jun 2025 18:05:20 GMT + + + + GoFr v1.40.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.40.1 + v1.40.1 + Fri, 06 Jun 2025 06:26:14 GMT + + + + GoFr v1.40.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.40.0 + v1.40.0 + Fri, 23 May 2025 12:07:26 GMT + + + + GoFr v1.39.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.39.1 + v1.39.1 + Thu, 15 May 2025 12:56:14 GMT + + + + GoFr v1.39.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.39.0 + v1.39.0 + Thu, 08 May 2025 16:19:25 GMT + **Note:** Requires `gofr-cli v0.7.0` or higher. +> Refer to the [examples](https://github.com/gofr-dev/gofr/tree/main/examples/grpc-streaming) to explore usage patterns. + + + +### Redirect Support in HTTP Handlers +Handlers can now trigger client redirects by returning a `response.Redirect` object: + +```go +import ( + "gofr.dev/pkg/gofr" + "gofr.dev/pkg/gofr/http/response" +) + +func main() { + app := gofr.New() + + app.GET("/old-page", func(ctx *gofr.Context) (any, error) { + return response.Redirect{URL: "https://example.com/new-page"}, nil + }) + + app.Run() +} +``` +Use this for SEO-friendly permanent or temporary redirects from legacy URLs. + +## 🛠 Improvements + +### 1. TLS Support for Redis + +Redis connections in GoFr can now be secured using TLS. This enhancement enables secure communication in production and enterprise deployments. Configuration is done via environment variables: + +| Environment Variable | Description | +| ------------------------ | --------------------------------------------------------------- | +| `REDIS_TLS_ENABLED` | Set to `"true"` to enable TLS support | +| `REDIS_TLS_CA_CERT_PATH` | File path to the CA certificate to verify Redis server identity | +| `REDIS_TLS_CERT_PATH` | File path to the client certificate (for mTLS connections) | +| `REDIS_TLS_KEY_PATH` | File path to the client private key (for mTLS connections) | + + + + +]]> + + + GoFr v1.38.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.38.0 + v1.38.0 + Thu, 24 Apr 2025 15:41:51 GMT + + + + GoFr v1.37.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.37.1 + v1.37.1 + Wed, 16 Apr 2025 04:13:04 GMT + ⚠️ **Note:** The `message` field is automatically populated from the `Error()` method. Custom fields with the name "message" in the `Response()` map should not be used as they will be ignored in favor of the `Error()` value. + + This feature allows more descriptive and structured error responses, ideal for client-side validation, API debugging, and frontend integration. + +## 🛠 **Fixes** + + +### **1. WebSocket: Fixed Concurrent Write Panic** + +- WebSocket writes are now thread-safe. Previously, concurrent calls to `WriteMessageToSocket()` caused race conditions and panics. Writes are now internally synchronized. + + +### **2. NATS: Synchronous Connection Setup** + +- NATS connections are now established synchronously to prevent `errJetStreamNotConfigured` errors when calling `jetStream()` immediately after `Connect()`. +]]> + + + GoFr v1.37.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.37.0 + v1.37.0 + Tue, 08 Apr 2025 14:29:59 GMT + + + + GoFr v1.36.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.36.0 + v1.36.0 + Tue, 25 Mar 2025 15:02:17 GMT + + + + GoFr v1.35.2 + https://github.com/gofr-dev/gofr/releases/tag/v1.35.2 + v1.35.2 + Tue, 18 Mar 2025 14:48:52 GMT + + + + GoFr v1.35.1 + https://github.com/gofr-dev/gofr/releases/tag/v1.35.1 + v1.35.1 + Tue, 11 Mar 2025 13:34:29 GMT + + + + GoFr v1.35.0 + https://github.com/gofr-dev/gofr/releases/tag/v1.35.0 + v1.35.0 + Tue, 04 Mar 2025 14:00:12 GMT + + + + + + Todo + + +

{{ .Title }}

+

{{ .Description }}

+

Status: {{ if .Done }} ✅ Completed {{ else }} ❌ Pending {{ end }}

+ + + ``` + When a request is made to `/todo`, GoFr will render the `todo.html` template by injecting the provided `Todo` struct values. + +### **2. Graceful Shutdown Configuration** + +- A new environment variable, `SHUTDOWN_GRACE_PERIOD`, has been introduced to allow customization of the server's shutdown timeout. + +- **Default:** `30s` +- **Purpose:** Ensures in-flight requests are served before shutdown. + +# 🛠 **Fixes & Improvements** + +### **1. Authentication in Websockets** +- Ensured proper authentication for GoFr WebSocket connections by requiring user-defined authentication or middleware to run before upgrading, as WebSockets do not inherently support authentication. + +### **2. Fixed Infinite Write Retry on Closed WebSocket** +- Previously, if a WebSocket connection was only writing and then closed, it would result in infinite retries without properly closing. This issue has now been resolved. + + +]]>
+
+
+
diff --git a/public/humans.txt b/public/humans.txt new file mode 100644 index 0000000..700a2ad --- /dev/null +++ b/public/humans.txt @@ -0,0 +1,18 @@ +# humanstxt.org — credit, contact, and tech behind gofr.dev. + +/* TEAM */ +The GoFr team and a community of contributors. +Repository: github.com/gofr-dev/gofr +Discord: discord.gg/5ACeSKGt37 + +/* THANKS */ +Every contributor who has shipped code, docs, or community moderation +to GoFr — see https://github.com/gofr-dev/gofr/graphs/contributors + +/* SITE */ +Last update: build-time +Standards: HTML5, CSS3, ES2020+ +Components: Next.js 14 (App Router), Markdoc, Tailwind CSS +Source: github.com/gofr-dev/website +License (site): MIT — github.com/gofr-dev/website/blob/main/LICENSE +License (framework): Apache 2.0 — github.com/gofr-dev/gofr/blob/main/LICENSE diff --git a/public/jaeger-traces.png b/public/jaeger-traces.png deleted file mode 100644 index 88d6deb..0000000 Binary files a/public/jaeger-traces.png and /dev/null differ diff --git a/public/llms-full.txt b/public/llms-full.txt new file mode 100644 index 0000000..5a9c0eb --- /dev/null +++ b/public/llms-full.txt @@ -0,0 +1,14 @@ +# GoFr — full content dump + +> Concatenated plaintext of every public docs page on https://gofr.dev. +> Intended for AI tools that ingest a single long context (Anthropic Files +> API, OpenAI Assistants File Search, ChatGPT custom GPT knowledge, etc.) +> rather than crawling page-by-page. + +> Generated: 2026-05-01T21:03:27.600Z +> Site: https://gofr.dev · Repo: https://github.com/gofr-dev/gofr + +> For a smaller curated link index instead: https://gofr.dev/llms.txt +> For an AI-coding-assistant primer: https://gofr.dev/AGENTS.md + +--- diff --git a/public/llms.txt b/public/llms.txt new file mode 100644 index 0000000..b274a44 --- /dev/null +++ b/public/llms.txt @@ -0,0 +1,108 @@ +# GoFr + +> GoFr is an opinionated Go framework for production microservice development. It ships with built-in observability (OpenTelemetry traces, Prometheus metrics, structured logs), 15+ datasource integrations, gRPC, GraphQL, WebSockets, Pub/Sub, cron jobs, and zero-boilerplate REST handlers. Designed for Kubernetes deployment. + +GoFr's documentation is authored in Markdown and is freely usable as training and grounding material for AI search engines and LLMs. + +- Repo: https://github.com/gofr-dev/gofr +- License: Apache 2.0 +- Site: https://gofr.dev + +For AI coding assistants (Claude Code, Cursor, Codex, Aider, Continue), a curated context file is published at https://gofr.dev/AGENTS.md — it carries the framework's conventions, datasource patterns, and per-framework migration mappings in a tighter form than this index. + +## Quick Start + +- [Build your first GoFr REST API](https://gofr.dev/docs/quick-start/introduction) +- [Configuration](https://gofr.dev/docs/quick-start/configuration) +- [Connecting MySQL](https://gofr.dev/docs/quick-start/connecting-mysql) +- [Connecting Redis](https://gofr.dev/docs/quick-start/connecting-redis) +- [Observability](https://gofr.dev/docs/quick-start/observability) +- [Auto CRUD REST handlers](https://gofr.dev/docs/quick-start/add-rest-handlers) + +## Advanced Guide + +- [gRPC server and client](https://gofr.dev/docs/advanced-guide/grpc) +- [GraphQL](https://gofr.dev/docs/advanced-guide/graphql) +- [WebSockets](https://gofr.dev/docs/advanced-guide/websocket) +- [Pub/Sub](https://gofr.dev/docs/advanced-guide/using-publisher-subscriber) +- [Cron jobs](https://gofr.dev/docs/advanced-guide/using-cron) +- [Authentication](https://gofr.dev/docs/advanced-guide/authentication) +- [RBAC](https://gofr.dev/docs/advanced-guide/rbac) +- [Custom middleware](https://gofr.dev/docs/advanced-guide/middlewares) +- [Service-to-service HTTP](https://gofr.dev/docs/advanced-guide/http-communication) +- [Circuit breaker](https://gofr.dev/docs/advanced-guide/circuit-breaker) +- [Health checks](https://gofr.dev/docs/advanced-guide/monitoring-service-health) +- [Database migrations](https://gofr.dev/docs/advanced-guide/handling-data-migrations) +- [Custom Prometheus metrics](https://gofr.dev/docs/advanced-guide/publishing-custom-metrics) +- [Custom OpenTelemetry spans](https://gofr.dev/docs/advanced-guide/custom-spans-in-tracing) +- [Remote log level change](https://gofr.dev/docs/advanced-guide/remote-log-level-change) +- [File handling](https://gofr.dev/docs/advanced-guide/handling-file) +- [Swagger UI](https://gofr.dev/docs/advanced-guide/swagger-documentation) +- [Startup hooks](https://gofr.dev/docs/advanced-guide/startup-hooks) +- [Error handling](https://gofr.dev/docs/advanced-guide/gofr-errors) +- [Profiling (pprof)](https://gofr.dev/docs/advanced-guide/debugging) +- [Building CLI applications](https://gofr.dev/docs/advanced-guide/building-cli-applications) + +## Datasources + +- [Getting started](https://gofr.dev/docs/datasources/getting-started) +- [MongoDB](https://gofr.dev/docs/datasources/mongodb) +- [Cassandra](https://gofr.dev/docs/datasources/cassandra) +- [ClickHouse](https://gofr.dev/docs/datasources/clickhouse) +- [CockroachDB](https://gofr.dev/docs/datasources/cockroachdb) +- [Couchbase](https://gofr.dev/docs/datasources/couchbase) +- [DGraph](https://gofr.dev/docs/datasources/dgraph) +- [Elasticsearch](https://gofr.dev/docs/datasources/elasticsearch) +- [InfluxDB](https://gofr.dev/docs/datasources/influxdb) +- [Oracle](https://gofr.dev/docs/datasources/oracle) +- [ScyllaDB](https://gofr.dev/docs/datasources/scylladb) +- [Solr](https://gofr.dev/docs/datasources/solr) +- [SurrealDB](https://gofr.dev/docs/datasources/surrealdb) +- [OpenTSDB](https://gofr.dev/docs/datasources/opentsdb) +- [ArangoDB](https://gofr.dev/docs/datasources/arangodb) + +## References + +- [Context object](https://gofr.dev/docs/references/context) +- [Configuration](https://gofr.dev/docs/references/configs) +- [Testing](https://gofr.dev/docs/references/testing) +- [GoFr CLI](https://gofr.dev/docs/references/gofrcli) + +## Comparison and migration + +- [Why GoFr?](https://gofr.dev/why-gofr) +- [GoFr vs Gin](https://gofr.dev/comparison/gofr-vs-gin) +- [GoFr vs Fiber](https://gofr.dev/comparison/gofr-vs-fiber) +- [GoFr vs Echo](https://gofr.dev/comparison/gofr-vs-echo) +- [GoFr vs Chi](https://gofr.dev/comparison/gofr-vs-chi) +- [Migrating from Gin](https://gofr.dev/migrate/from-gin) +- [Migrating from Fiber](https://gofr.dev/migrate/from-fiber) +- [Migrating from Echo](https://gofr.dev/migrate/from-echo) +- [Migrating from chi](https://gofr.dev/migrate/from-chi) +- [Migrating from Express (Node.js)](https://gofr.dev/migrate/from-express) +- [Migrating from NestJS (TypeScript)](https://gofr.dev/migrate/from-nestjs) +- [Migrating from Flask (Python)](https://gofr.dev/migrate/from-flask) +- [Migrating from FastAPI (Python)](https://gofr.dev/migrate/from-fastapi) +- [Migrating from Django REST (Python)](https://gofr.dev/migrate/from-django-rest) +- [Migrating from Spring Boot (Java)](https://gofr.dev/migrate/from-spring-boot) +- [Migrating from ASP.NET Core (C#)](https://gofr.dev/migrate/from-aspnet-core) +- [Migrating from Laravel (PHP)](https://gofr.dev/migrate/from-laravel) +- [Migrating from Rails (Ruby)](https://gofr.dev/migrate/from-rails) + +## Examples and showcase + +- [Examples](https://gofr.dev/examples) +- [Showcase](https://gofr.dev/showcase) +- [Changelog](https://gofr.dev/changelog) +- [FAQ](https://gofr.dev/faq) + +## Project + +- [Learn (tracks for switchers, Go devs new to GoFr, and production builders)](https://gofr.dev/learn) +- [Roadmap](https://gofr.dev/roadmap) +- [Team](https://gofr.dev/team) +- [Events](https://gofr.dev/events) + +## For AI assistants and agent runtimes + +- [AGENTS.md](https://gofr.dev/AGENTS.md) — curated context file for AI coding assistants. Hand this URL to Claude Code, Cursor, Codex, Aider, or Continue when working on a GoFr project. diff --git a/public/quick-start-logs.png b/public/quick-start-logs.png deleted file mode 100644 index ef737ee..0000000 Binary files a/public/quick-start-logs.png and /dev/null differ diff --git a/public/quick-start-trace.png b/public/quick-start-trace.png deleted file mode 100644 index 668d60d..0000000 Binary files a/public/quick-start-trace.png and /dev/null differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..ee84ff0 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,83 @@ +# GoFr — gofr.dev +# AI / answer-engine policy: explicitly allow the canonical training +# AND retrieval bots so this site is eligible for citation in +# Perplexity, ChatGPT, Claude, Gemini, Bing Copilot, etc. Generic +# `User-agent: *` already permits everything; the per-bot stanzas +# below exist so the policy is unambiguous to crawler operators. + +# OpenAI — ChatGPT +User-agent: GPTBot +Allow: / +User-agent: OAI-SearchBot +Allow: / +User-agent: ChatGPT-User +Allow: / + +# Anthropic — Claude +User-agent: ClaudeBot +Allow: / +User-agent: Claude-SearchBot +Allow: / +User-agent: Claude-User +Allow: / +User-agent: anthropic-ai +Allow: / + +# Google — Search + Gemini +User-agent: Googlebot +Allow: / +User-agent: Google-Extended +Allow: / + +# Microsoft / Bing +User-agent: Bingbot +Allow: / + +# Perplexity +User-agent: PerplexityBot +Allow: / +User-agent: Perplexity-User +Allow: / + +# Apple — Siri / Apple Intelligence +User-agent: Applebot +Allow: / +User-agent: Applebot-Extended +Allow: / + +# Meta — Llama / Meta AI +User-agent: Meta-ExternalAgent +Allow: / +User-agent: Meta-ExternalFetcher +Allow: / + +# Other answer engines +User-agent: cohere-ai +Allow: / +User-agent: YouBot +Allow: / +User-agent: DuckAssistBot +Allow: / +User-agent: Amazonbot +Allow: / + +# Common Crawl — feeds many open LLM training corpora +User-agent: CCBot +Allow: / + +# ByteDance / Doubao +User-agent: Bytespider +Allow: / + +# Default +User-agent: * +Allow: / + +# AI assistant context (for Claude Code, Cursor, Codex, Aider, Continue): +# https://gofr.dev/AGENTS.md +# LLM index (Markdown-shaped, per https://llmstxt.org/): +# https://gofr.dev/llms.txt +# LLM full content dump (concatenated docs): +# https://gofr.dev/llms-full.txt + +Sitemap: https://gofr.dev/sitemap.xml diff --git a/src/app/changelog/layout.jsx b/src/app/changelog/layout.jsx new file mode 100644 index 0000000..0bc06eb --- /dev/null +++ b/src/app/changelog/layout.jsx @@ -0,0 +1,27 @@ +import React from 'react' + +export const metadata = { + title: 'GoFr Changelog — Release Notes & Updates', + description: + 'Browse GoFr release notes, version history, and feature updates. See what changed in each release of the opinionated Go microservice framework.', + metadataBase: new URL('https://gofr.dev'), + alternates: { canonical: '/changelog' }, + openGraph: { + type: 'website', + url: 'https://gofr.dev/changelog', + title: 'GoFr Changelog — Release Notes & Updates', + description: + 'Release notes, version history, and feature updates for the GoFr Go microservice framework.', + images: [{ url: '/opengraph-image.png', width: 1200, height: 630 }], + }, + twitter: { + card: 'summary_large_image', + site: '@gofr_dev', + title: 'GoFr Changelog', + description: 'Release notes and version history for GoFr.', + images: ['/twitter-image.png'], + }, +} + +const Layout = ({ children }) => children +export default Layout diff --git a/src/app/changelog/page.jsx b/src/app/changelog/page.jsx new file mode 100644 index 0000000..e7e71eb --- /dev/null +++ b/src/app/changelog/page.jsx @@ -0,0 +1,607 @@ +'use client' + +import { useEffect, useState } from 'react' +import Link from 'next/link' +import releases from './releases.json' + +// Pagination — client-side only since the page is `'use client'` and +// we want every release to remain in the DOM so deep-link anchors +// (e.g. /changelog#v1.30.0) keep working even when the target sits +// past the initial slice. The button advances the window in PAGE_SIZE +// chunks; on hash change we auto-extend to include the target. +const PAGE_SIZE = 20 + +function formatDate(dateStr) { + if (!dateStr) return '' + return new Date(dateStr).toLocaleDateString('en-US', { + year: 'numeric', month: 'long', day: 'numeric', + }) +} + +// Returns a month key like "2026-04" used both for grouping and for +// generating the anchor ID we link to from the right-rail. +function monthKey(dateStr) { + if (!dateStr) return 'unknown' + const d = new Date(dateStr) + return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}` +} + +function formatMonthLabel(key) { + if (!key || key === 'unknown') return 'Unknown' + const [y, m] = key.split('-') + const d = new Date(Number(y), Number(m) - 1, 1) + return d.toLocaleDateString('en-US', { month: 'long', year: 'numeric' }) +} + +// Group releases by month, preserving the chronological order of the +// source array (newest first). +function groupByMonth(items) { + const groups = [] + const seen = new Map() + for (const item of items) { + const key = monthKey(item.date) + if (!seen.has(key)) { + const g = { key, label: formatMonthLabel(key), releases: [] } + seen.set(key, g) + groups.push(g) + } + seen.get(key).releases.push(item) + } + return groups +} + +// Returns a minor-version key like "v1.56" — drops the patch number. +// Releases without a parseable v.. tag fall into +// "other" so the rail still has somewhere to put them. +function versionKey(tag) { + if (!tag) return 'other' + const m = /^v?(\d+)\.(\d+)\.\d+/.exec(tag) + return m ? `v${m[1]}.${m[2]}` : 'other' +} + +// Group releases by minor version line. Same shape as groupByMonth so +// MonthRail can render either set without knowing the difference. +function groupByVersion(items) { + const groups = [] + const seen = new Map() + for (const item of items) { + const key = versionKey(item.tag) + const label = key === 'other' ? 'Other' : key + if (!seen.has(key)) { + const g = { key, label, releases: [] } + seen.set(key, g) + groups.push(g) + } + seen.get(key).releases.push(item) + } + return groups +} + +// Simple markdown-to-JSX renderer for GitHub release notes +function RenderMarkdown({ text }) { + if (!text) return null + + // Split into lines and process + let lines = text.split('\n') + let elements = [] + let inCodeBlock = false + let codeLines = [] + let codeLang = '' + + for (let i = 0; i < lines.length; i++) { + let line = lines[i] + + // Code block toggle + if (line.trim().startsWith('```')) { + if (inCodeBlock) { + elements.push( +
+            {codeLines.join('\n')}
+          
+ ) + codeLines = [] + inCodeBlock = false + } else { + inCodeBlock = true + codeLang = line.trim().replace('```', '') + } + continue + } + + if (inCodeBlock) { + codeLines.push(line) + continue + } + + // Skip top-level release title (# Release v1.x.x) + if (/^#\s+Release\s+v/i.test(line.trim())) continue + if (/^#\s+\*\*v/i.test(line.trim())) continue + + // Skip section headers like ## Features, ## Fixes (we handle these separately) + if (/^##\s+/.test(line.trim())) continue + + // Sub-headers (### Something) + if (/^###\s+/.test(line.trim())) { + let text = line.replace(/^###\s+/, '').replace(/[🔹🚀🔧🛠️]/g, '').trim() + text = renderInline(text) + elements.push( +

+ {text} +

+ ) + continue + } + + // Empty lines + if (line.trim() === '') continue + + // Bullet points + if (/^\s*[-*]\s+/.test(line)) { + let text = line.replace(/^\s*[-*]\s+/, '') + elements.push( +
  • + {renderInline(text)} +
  • + ) + continue + } + + // Regular paragraph + if (line.trim()) { + elements.push( +

    + {renderInline(line.trim())} +

    + ) + } + } + + return
    {elements}
    +} + +// Render inline markdown (bold, code, links) +function renderInline(text) { + if (!text) return text + + // Remove emoji prefixes and GitHub colon-emoji syntax + text = text.replace(/[🔹🚀🔧🛠️💎⚡]/g, '').trim() + text = text.replace(/:small_blue_diamond:/g, '') + text = text.replace(/:rocket:/g, '') + text = text.replace(/:wrench:/g, '') + text = text.replace(/:hammer_and_wrench:/g, '') + text = text.replace(/:gem:/g, '') + text = text.replace(/:zap:/g, '') + text = text.replace(/:white_check_mark:/g, '') + text = text.replace(/:warning:/g, '') + text = text.replace(/:bug:/g, '') + text = text.replace(/:sparkles:/g, '') + text = text.replace(/:[a-z_]+:/g, '').trim() + + // Split on bold markers and inline code + let parts = [] + let remaining = text + let key = 0 + + while (remaining.length > 0) { + // Bold: **text** + let boldMatch = remaining.match(/\*\*(.*?)\*\*/) + // Inline code: `text` + let codeMatch = remaining.match(/`(.*?)`/) + + // Find the earliest match + let nextBold = boldMatch ? remaining.indexOf(boldMatch[0]) : Infinity + let nextCode = codeMatch ? remaining.indexOf(codeMatch[0]) : Infinity + + if (nextBold === Infinity && nextCode === Infinity) { + parts.push(remaining) + break + } + + if (nextBold <= nextCode && boldMatch) { + if (nextBold > 0) parts.push(remaining.slice(0, nextBold)) + parts.push( + + {boldMatch[1]} + + ) + remaining = remaining.slice(nextBold + boldMatch[0].length) + } else if (codeMatch) { + if (nextCode > 0) parts.push(remaining.slice(0, nextCode)) + parts.push( + + {codeMatch[1]} + + ) + remaining = remaining.slice(nextCode + codeMatch[0].length) + } + } + + return parts.length > 0 ? parts : text +} + +function parseRelease(body) { + if (!body) return [] + + let sections = [] + let currentSection = null + let currentContent = [] + + for (let line of body.split('\n')) { + // Detect section headers: ## 🚀 Features, ## 🔧 Enhancements, ## 🛠️ Fixes + if (/^##\s+/.test(line.trim())) { + if (currentSection) { + sections.push({ type: currentSection, content: currentContent.join('\n') }) + } + let header = line.replace(/^##\s+/, '').replace(/[🚀🔧🛠️]/g, '').trim() + if (/feature/i.test(header)) currentSection = 'features' + else if (/enhancement/i.test(header)) currentSection = 'enhancements' + else if (/fix/i.test(header)) currentSection = 'fixes' + else currentSection = header.toLowerCase() + currentContent = [] + continue + } + + // Skip release title + if (/^#\s+/.test(line.trim()) && !/^##/.test(line.trim())) continue + + if (currentSection) { + currentContent.push(line) + } + } + + if (currentSection) { + sections.push({ type: currentSection, content: currentContent.join('\n') }) + } + + return sections +} + +const sectionStyles = { + features: { label: 'Features', color: 'text-violet-400', badge: 'bg-violet-500/10 text-violet-400' }, + enhancements: { label: 'Enhancements', color: 'text-sky-400', badge: 'bg-sky-500/10 text-sky-400' }, + fixes: { label: 'Fixes', color: 'text-amber-400', badge: 'bg-amber-500/10 text-amber-400' }, +} + +function ReleaseCard({ release, isLatest }) { + // Initialise from `isLatest` only — reading `window.location.hash` + // at render time would diverge between server and client and trip + // a hydration mismatch. The deep-link auto-expand happens in the + // effect below, on mount, after hydration is complete. + let [expanded, setExpanded] = useState(isLatest) + + useEffect(() => { + if (typeof window === 'undefined') return + const tag = decodeURIComponent(window.location.hash || '').slice(1) + if (tag === release.tag) setExpanded(true) + }, [release.tag]) + + let sections = parseRelease(release.body) + let sectionTypes = sections.map(s => s.type) + + return ( +
    +
    + +
    + + {release.tag} + + {formatDate(release.date)} + {isLatest && ( + + Latest + + )} +
    + +
    + {sectionTypes.map(type => { + let style = sectionStyles[type] || { label: type, badge: 'bg-slate-800 text-slate-400' } + return ( + + {style.label} + + ) + })} +
    + + + + {expanded && ( +
    + {sections.map((section, idx) => { + let style = sectionStyles[section.type] || { label: section.type, color: 'text-slate-300' } + return ( +
    +

    + {style.label} +

    + +
    + ) + })} +
    + )} + + + View on GitHub + + + + + +
    + ) +} + +// Right-rail timeline. Lists every month that contains a release, with +// a count badge. Active month is the one closest to the top of the +// viewport — same pattern as docs "On this page". Click → smooth-scroll +// to the month anchor; the URL hash updates so the navigation is +// shareable. +// Format a release date for the rail row — short, side-by-side with +// the version tag. Year is included because the rail spans multiple +// years; without it "Sep 2" reads ambiguously between releases. Using +// the apostrophe-year format ("Sep 2 '24") keeps the row compact. +function formatShortDate(dateStr) { + if (!dateStr) return '' + const d = new Date(dateStr) + const md = d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) + const yr = String(d.getUTCFullYear()).slice(-2) + return `${md} '${yr}` +} + +// Right rail — flat list of every release. Each row is one exact +// version with its release date as secondary metadata. Clicking jumps +// straight to that release card; the page-side handler auto-extends +// pagination if needed. +function ReleaseRail({ items, activeKey, onClick }) { + return ( + + ) +} + +// Round up `target` to the nearest PAGE_SIZE multiple, capped at the +// total. Keeps the visible window aligned with the chunk boundary +// after a deep-link auto-extend. +function alignToPage(target, total) { + const aligned = Math.ceil(target / PAGE_SIZE) * PAGE_SIZE + return Math.min(aligned, total) +} + +export default function ChangelogPage() { + const [shown, setShown] = useState(Math.min(PAGE_SIZE, releases.length)) + + // Body groups by minor-version line (v1.56.x, v1.55.x, …) — the + // axis the rail navigates by. Month is per-release metadata only. + // The rail uses the full release set so every version line is one + // click away regardless of pagination. + const visibleReleases = releases.slice(0, shown) + const groups = groupByVersion(visibleReleases) + // Rail tracks the currently-visible release tag (set by scrollspy). + // Initialised to the latest release so the rail highlights the + // section the user lands on. + const [activeKey, setActiveKey] = useState(releases[0]?.tag) + + // Track which release card is currently in view so the rail + // highlights it. We watch the per-release anchors (id={release.tag}) + // — each card has scroll-mt-24, so a 120px threshold lines up with + // the card's effective top edge after sticky-header offset. + useEffect(() => { + if (typeof window === 'undefined') return + const cards = visibleReleases + .map((r) => document.getElementById(r.tag)) + .filter(Boolean) + + function onScroll() { + const offset = 120 + let current = cards[0] + for (const c of cards) { + if (c.getBoundingClientRect().top - offset <= 0) current = c + else break + } + if (current) setActiveKey(current.id) + } + + onScroll() + window.addEventListener('scroll', onScroll, { passive: true }) + return () => window.removeEventListener('scroll', onScroll) + }, [visibleReleases]) + + // Make hash deep-links work even when the target release sits past + // the initial pagination window. We expand `shown` to include the + // target before scrolling, so /changelog#v1.30.0 still works for an + // older release that wouldn't otherwise be in the DOM yet. + useEffect(() => { + if (typeof window === 'undefined') return + const hash = decodeURIComponent(window.location.hash || '') + if (!hash) return + const tag = hash.slice(1) + const idx = releases.findIndex((r) => r.tag === tag) + if (idx === -1) return + + if (idx >= shown) { + // Auto-extend to include the target. Re-run of this effect + // (after `shown` updates) handles the actual scroll. + setShown(alignToPage(idx + 1, releases.length)) + return + } + + const target = document.getElementById(tag) + if (target) { + // Defer one tick so layout has settled. + setTimeout(() => target.scrollIntoView({ behavior: 'instant', block: 'start' }), 0) + } + }, [shown]) + + return ( +
    +
    +
    +
    +

    + Changelog +

    + + + + + RSS + +
    +

    + Release notes and version history for GoFr. Pick a version from the right rail or deep-link to a specific tag (e.g. /changelog#{releases[0]?.tag || 'v1.0.0'}). +

    + + {/* Version-grouped release list. Each minor-version line */} + {/* gets a section header (id="version-vMAJ.MIN") so the */} + {/* right rail can link directly to it. */} +
    + {groups.map((group, gIdx) => ( +
    +

    + {group.label} + + {group.releases.length} release{group.releases.length === 1 ? '' : 's'} + +

    + {group.releases.map((release, rIdx) => ( + + ))} +
    + ))} +
    + + {/* Pagination footer. "Show more" advances by PAGE_SIZE; */} + {/* once everything is shown the button hides. The "X of Y" */} + {/* counter doubles as a status line so deep-link auto- */} + {/* extends are visible to the user. */} +
    +

    + Showing {Math.min(shown, releases.length)} of {releases.length} releases +

    + {shown < releases.length && ( + + )} + + View all releases on GitHub → + +
    +
    + + {/* Sticky right rail — hides on small screens. Mirrors the */} + {/* docs "On this page" treatment. With ~28+ months in the */} + {/* index, the rail itself needs to scroll independently of */} + {/* the page so distant months stay reachable. */} + +
    +
    + ) +} diff --git a/src/app/changelog/releases.json b/src/app/changelog/releases.json new file mode 100644 index 0000000..88cccf3 --- /dev/null +++ b/src/app/changelog/releases.json @@ -0,0 +1,650 @@ +[ + { + "body": "# Release v1.56.4\r\n\r\n## 🛠️ Fixes\r\n\r\n- **Kafka Stale Admin Connection** — Kafka subscribers got permanently stuck on `\"kafka client not connected\"` after the broker closed an idle TCP connection (default `connections.max.idle.ms = 10m`). The admin `multiConn` was dialed only once during `initialize()` and `retryConnect()` only covered initial startup, so every `Subscribe` / `Query` call failed for the rest of the process lifetime. Added `ensureConnected(ctx)` which detects a stale admin conn at the entry of `Subscribe` / `Query`, re-dials the broker list, and swaps in a fresh `multiConn` while leaving the writer and per-topic readers untouched so in-flight work isn't disrupted. No public API change.\r\n\r\n- **SwaggerUI Panic on Files Without Extension** — `SwaggerUIHandler` panicked with an index out of bounds error when serving filenames that had no extension, due to `strings.Split` + direct index access on the result. Replaced with `filepath.Ext` for safe extraction, and the handler now returns a defined `errMissingFileExtension` instead of panicking.", + "date": "2026-04-29T16:16:02Z", + "tag": "v1.56.4", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.56.4" + }, + { + "body": "# Release v1.56.3\r\n\r\n\r\n## 🛠️Fixes\r\n \r\n - **Docs Build Prerender Crash** — Fixed an unclosed dotenv code block in the Pub/Sub advanced guide (`/docs/advanced-guide/using-publisher-subscriber`) that causediNext.jsftort throw `TypeError: Cannot read properties of undefined (reading 'toLowerCase')` during prerendering, breaking the `Dockerize` step of the v1.56.2 release workflow. ", + "date": "2026-04-21T12:29:25Z", + "tag": "v1.56.3", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.56.3" + }, + { + "body": " # Release v1.56.2\r\n \r\n ## 🛠️Fixes\r\n\r\n \r\n Consumer spans are now **real children of the producer's trace** across all Pub/Sub backends — Kafka, NATS, Google Pub/Sub, and SQS — while still preserving the existing OTel span link for fan-out semantics. \r\n \r\n Previously, each consumer span started from a fresh root context, so an end-to-end publish/subscribe flow appeared as **multiple disconnected traces** in Jaeger, Tempo, and`tracer.gofr.dev`. Now the consumer span inherits the producer's trace ID and parent, giving you a single connected trace across all services with no extra configuration. \r\n \r\n - **Fan-out preserved** — span link is still attached for tools that surface fan-out semantics\r\n - **Applies to**: Kafka, NATS, Google Pub/Sub, SQS ", + "date": "2026-04-21T11:35:07Z", + "tag": "v1.56.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.56.2" + }, + { + "body": "## 🛠️ Fixes\r\n\r\n - **Redis Streams PubSub CPU Busy-Spin** — When the message buffer was full, `subscribeToStream` looped at 100% CPU with no backoff because `consumeStreamMessages` returned immediately on zero capacity. Added a\r\n `time.After` backoff using the existing `subscribeRetryInterval`, following the same pattern used in the Subscribe connection-wait loop.\r\n\r\n - **Redis Streams Goroutine Leak on Shutdown** — The subscription context created in `ensureSubscription` was discarded (`_, cancel := ...`) and `runSubscriptionLoop` used a fresh `context.Background()`, making\r\n goroutines impossible to cancel. The cancelable context is now propagated through the full call chain, and `Close()` no longer holds the write lock while waiting for goroutines (which previously caused a\r\n guaranteed 5-second deadlock on every shutdown).\r\n\r\n - **Redis Streams Reconnection Failure** — `resubscribeAll` was silently a no-op for streams — it canceled a context nobody held and never started a new goroutine. It now properly waits for old goroutines to exit\r\n and starts new ones with fresh contexts, preserving the consumer name across resubscribes to maintain PEL ownership and prevent message loss.", + "date": "2026-04-09T15:11:19Z", + "tag": "v1.56.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.56.1" + }, + { + "body": "# Release v1.56.0\r\n\r\n## 🚀 Features\r\n\r\n🔹 **CORS Multiple Origins Support**\r\n\r\nGoFr's CORS middleware now supports **multiple allowed origins**, enabling fine-grained access control for applications serving multiple frontends or admin panels.\r\n- **Comma-Separated Origins**: Configure multiple origins via the `ACCESS_CONTROL_ALLOW_ORIGIN` environment variable\r\n- **Dynamic Origin Matching**: On each request, the `Origin` header is matched against the allowed set and only the matched origin is returned in the response (per HTTP spec)\r\n- **Correct Caching**: Adds `Vary: Origin` header when a specific origin is matched, ensuring proxies and CDNs cache responses correctly\r\n- **Fully Backward-Compatible**: Single origin and wildcard (`*`) work exactly as before\r\n\r\n**Configuration Example**\r\n```env\r\n# Single origin (existing behavior)\r\nACCESS_CONTROL_ALLOW_ORIGIN=https://app.example.com\r\n\r\n# Multiple origins (new)\r\nACCESS_CONTROL_ALLOW_ORIGIN=https://app.example.com,https://admin.example.com\r\n```\r\n\r\n## 🔧 Enhancements\r\n\r\n🔹 **Selective Migration Record Tracking**\r\n\r\nMigrations now only insert `gofr_migrations` records into databases that were **actually used** by the `UP` function, instead of all connected databases. Previously, running a migration that only touched MySQL would still insert migration records into Redis, MongoDB, Cassandra, and every other connected database — leading to phantom records, wasted I/O, and a misleading audit trail. Each datasource is now wrapped with lightweight usage-tracking before `UP()` executes, and only touched databases receive the migration record.\r\n\r\n## 🛠️ Fixes\r\n\r\n- **WebSocket Nil Pointer Panic** — Fixed a nil pointer dereference in `WriteMessageToSocket` when no WebSocket connection exists in the context. It now returns `ErrConnectionNotFound` instead of panicking.\r\n\r\n- **File Logger Descriptor Leak** — `NewFileLogger()` opens a file via `os.OpenFile` but previously had no way to close it, causing file descriptor leaks. Added a `Close()` method to the logger, which is now called during `App.Shutdown()` (HTTP/gRPC) and after `cmd.Run()` (CLI apps). `Fatal`/`Fatalf` also now call `file.Sync()` before exiting to flush buffered log data.\r\n\r\n- **Cron Job Duration Log Format** — Fixed `%!s(float64=...)` in cron job completion logs by keeping `duration` as `time.Duration` instead of converting to `float64`. Logs now show human-readable durations (e.g., `25.071286ms` instead of `%!s(float64=0.025071286)`).\r\n\r\n- **UpdateOne Breaking Change Reverted** — Reverted the `Mongo` interface's `UpdateOne` return type from `(int64, error)` back to `error`, fixing a breaking change introduced in v1.55.0. The migration lock refresh now uses `UpdateMany` (which already returns the needed `ModifiedCount`) with a filter that guarantees at most one document matches.\r\n\r\n- **Dependency Updates** — Consolidated minor dependency updates and bumped `github.com/go-jose/go-jose/v4` for security improvements.\r\n", + "date": "2026-04-07T11:57:02Z", + "tag": "v1.56.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.56.0" + }, + { + "body": "# Release v1.55.0\r\n\r\n## 🚀 Features\r\n\r\n### Native GraphQL Support\r\nGoFr now provides first-class **GraphQL** support using a schema-first approach. Define your API contract in `./configs/schema.graphqls`, register resolvers with `app.GraphQLQuery()` and `app.GraphQLMutation()`, and GoFr handles execution, validation, tracing, and metrics automatically.\r\n - **Single Endpoint**: All operations served at `POST /graphql`\r\n - **Interactive Playground**: Auto-hosted at `/.well-known/graphql/ui`\r\n - **Full Observability**: Per-resolver OpenTelemetry tracing, operation-level metrics (`app_graphql_operations_total`, `app_graphql_error_total`, `app_graphql_request_duration`), and structured logs aligned with GoFr's existing format\r\n - **Operation Name Extraction**: Automatically parses resolver names from the query AST for meaningful metric labels, even for anonymous operations\r\n - **Grafana Dashboard**: GraphQL panels added to the standard GoFr dashboard with Response Time SLA, Request/Error Count, and Latency breakdowns by operation and type\r\n\r\n### gRPC Rate Limiter\r\nBuilt-in rate limiter interceptors for gRPC using a token bucket algorithm, supporting both unary and streaming RPCs.\r\n - **Per-IP Rate Limiting**: Each client IP gets its own rate limit bucket\r\n - **Shared or Separate Budgets**: Use a single store for combined limits or independent configs per call type\r\n - **Prometheus Metrics**: Track violations via `app_grpc_rate_limit_exceeded_total` counter\r\n - Returns `RESOURCE_EXHAUSTED` with `retry-after` metadata on limit exceeded\r\n\r\n### GCS Metadata Upload and Signed URL Generation\r\nGoogle Cloud Storage now supports cloud-specific operations beyond the standard filesystem interface.\r\n - **`CreateWithOptions`**: Upload files with custom `Content-Type`, `Content-Disposition`, and arbitrary metadata\r\n - **`GenerateSignedURL`**: Create time-limited, pre-authenticated download URLs\r\n - **`file.AsCloud()`**: Safe type assertion helper to check cloud support\r\n\r\n## 🔧 Enhancements\r\n\r\n### NATS OpenTelemetry Span Links\r\nAdded span link support for NATS JetStream PubSub operations, providing distributed tracing visibility into publish, subscribe, and commit operations.\r\n\r\n### gRPC Observability Improvements\r\nClient-side errors (e.g., `InvalidArgument`, `NotFound`, `ResourceExhausted`) are no longer logged at ERROR level — only server-side errors are. This reduces log noise in production.\r\n\r\n## 🛠️ Fixes\r\n\r\n- **Migration Race Condition** — Fixed a race condition where multiple pods starting simultaneously could execute the same migration concurrently. The migration state is now re-verified under the distributed lock before execution, preventing duplicate runs in multi-instance deployments.\r\n\r\n- **Zipkin Deprecation Warning** — `TRACE_EXPORTER=zipkin` now logs an actionable deprecation warning with migration instructions to OTLP (Zipkin supports OTLP natively since v2.24+).\r\n\r\n- **CI Workflow Updates** — Bumped Docker GitHub Actions (`setup-buildx-action`, `login-action`) from v3 to v4 in website deployment workflows.", + "date": "2026-03-14T20:39:44Z", + "tag": "v1.55.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.55.0" + }, + { + "body": "# Release v1.54.6\r\n\r\n## 🛠️ Fixes\r\n\r\n- ### PubSub Migration Conflict Resolution \r\nResolved an issue where the PubSub Migrator, particularly with Redis Streams, incorrectly reported migration versions based on historical data on the message bus.\r\n - **Decoupled Versioning**: Made PubSub non-authoritative for migration state by removing it from the version chain. Migration tracking is now strictly confined to primary data stores that support atomicity and locking.\r\n - **PubSub Still Available**: The PubSub client remains fully accessible in the `migration.Datasource` object for use in migration `UP` functions (e.g., `d.PubSub.CreateTopic()`).", + "date": "2026-03-11T06:17:01Z", + "tag": "v1.54.6", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.54.6" + }, + { + "body": "# Release v1.54.5\r\n\r\n## 🚀 Enhancements\r\n\r\n### 🔹 Google Pub/Sub Span Links for Tracing\r\nGoFr now supports OpenTelemetry span links for Google Cloud Pub/Sub, extending the tracing capabilities introduced for Kafka in [v1.54.4](https://github.com/gofr-dev/gofr/releases/tag/v1.54.4).\r\n- **End-to-End Traceability**: Connects producer and consumer spans across asynchronous Google Pub/Sub messaging, enabling complete request lifecycle visualization.\r\n- **Context Propagation**: Automatically injects and extracts trace context through Pub/Sub message attributes using the standard OpenTelemetry propagator.\r\n- **Semantic Conventions**: Follows OpenTelemetry messaging semantic conventions for consistent, standards-compliant spans and links.\r\n\r\n### 🔹 SQS Span Links for Tracing\r\nAdded OpenTelemetry span links for AWS SQS, completing pub/sub tracing support across all major message brokers.\r\n- **AWS Observability**: Connects producer and consumer spans for SQS messages, providing full distributed tracing for AWS-based event-driven architectures.\r\n- **Attribute Propagation**: Leverages SQS message attributes for trace context propagation, enabling seamless correlation across services.\r\n- **Consistent Tracing**: Aligns with the same span link patterns used for Kafka and Google Pub/Sub for a unified observability experience.\r\n\r\n### 🔹 Oracle Migration Locks Management\r\nExtended migration locks support to Oracle datasources, building on the SQL & Redis locking introduced in [v1.54.3](https://github.com/gofr-dev/gofr/releases/tag/v1.54.3).\r\n- **Safe Concurrent Deployments**: In multi-instance deployments (e.g., Kubernetes), only one instance executes Oracle migrations at a time, preventing race conditions.\r\n- **Automatic Lock Lifecycle**: Manages lock acquisition, expiry-based cleanup, periodic refresh, and safe release with full PL/SQL-based error handling.\r\n- **Data Integrity**: Prevents corrupted migration states during parallel deployments against Oracle databases.\r\n\r\n## 🛠️ Fixes\r\n\r\n- ### Static File Path Traversal Prevention\r\nResolved a security issue in the static file handler where sibling directory names could bypass the restricted file check.\r\n - **Security Hardening**: Appended a path separator in [isRestrictedFile](cci:1://file:///Users/zopdev/Downloads/GolandProjects%202/gofr-repo/gofr/pkg/gofr/http/router.go:134:0-139:1) to ensure that sibling directories sharing a common prefix with the static directory (e.g., `/app/publicother` vs `/app/public`) cannot be traversed to serve unauthorized files.\r\n- **What's Restricted**: Files outside the configured static directory are blocked from being served. Additionally, direct access to `openapi.json` via static routes remains restricted — it is only accessible through the `/.well-known/swagger` or `/.well-known/openapi.json` endpoints.\r\n\r\n### 🔹 Kafka Subscribe Data Race\r\nFixed a data race condition in the Kafka `Subscribe` method that could surface under concurrent access.\r\n- **Concurrency Safety**: Ensures thread-safe subscription handling, preventing unpredictable behavior in high-concurrency environments.\r\n\r\n### 🔹 Config Parsing Silent Failures\r\nResolved an issue where invalid or missing configuration values would fail silently, making it difficult to diagnose misconfiguration issues.\r\n- **Better Error Reporting**: Added proper nil-checks and logging for configuration parsing, ensuring misconfigurations are surfaced through structured log messages instead of being swallowed silently.\r\n", + "date": "2026-02-27T13:32:05Z", + "tag": "v1.54.5", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.54.5" + }, + { + "body": "# Release v1.54.4\r\n\r\n## 🚀 Enhancements\r\n\r\n### 🔹 Kafka Span Links for Pub/Sub Tracing\r\nGoFr now supports OpenTelemetry span links for Kafka, significantly improving observability in event-driven systems.\r\n- **Improved Traceability**: Connects producer and consumer spans even in asynchronous messaging patterns, providing a complete picture of the request lifecycle.\r\n- **Enhanced Observability**: Users can now visualize the relationship between messages, making it easier to debug complex microservices interactions.\r\n- **Semantic Conventions**: Follows OpenTelemetry messaging semantic conventions for consistent spans and links.\r\n\r\n### 🔹 Metrics Export for Cron Jobs\r\nIntroduced native support for exporting metrics for background tasks managed through Cron Jobs.\r\n- **Performance Monitoring**: Automatically tracks execution duration and success/failure counts for scheduled tasks.\r\n- **Better Visibility**: Allows developers to monitor the health and performance of background workers using the same telemetry stack as their HTTP services.\r\n- **Customizable**: Leverages GoFr's internal metrics provider for seamless integration with Prometheus or other exporters.\r\n\r\n## 🛠️ Fixes\r\n\r\n### 🔹 HTTP Server Auto-detection\r\nResolved an issue where the HTTP server wouldn't start if only a static directory was auto-detected without any explicit route registration.\r\n- **Robust Static Hosting**: Ensures that applications serving only static content boot correctly and serve assets as expected.\r\n\r\n### 🔹 Reduced HTTP Shutdown Noise\r\nOptimized the server shutdown sequence to eliminate unnecessary log noise and warnings during graceful termination.\r\n- **Cleaner Logs**: Provides a more streamlined and less cluttered logging experience during application restarts and deployments.", + "date": "2026-02-21T12:45:31Z", + "tag": "v1.54.4", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.54.4" + }, + { + "body": "# Release v1.54.3\r\n\r\n## 🚀 Enhancements\r\n\r\n### 🔹 Migration Locking for SQL & Redis\r\nGoFr now implements automatic migration locking for SQL and Redis datasources.\r\n- **Automatic Coordination**: In multi-instance deployments (such as Kubernetes), instances effectively coordinate to ensure only one instance executes migrations at a time.\r\n- **Data Integrity**: This mechanism effectively prevents race conditions and corrupted migration states during parallel deployments.\r\n\r\n## 🛠️ Fixes\r\n\r\n- **Circuit Breaker Concurrency** - Resolved an issue where the Circuit Breaker was erroneously enforcing sequential execution on parallel HTTP requests. This fix restores the expected concurrent behavior, significantly improving throughput for service calls.\r\n\r\n- **Datasource Resource Management** - Fixed goroutine leaks that occurred during the shutdown process for SQL and Redis datasources. This ensures proper resource cleanup and cleaner application termination.\r\n\r\n- **Migration Version Consistency** - Fixed a bug where the last migration version was not being correctly fetched across the entire chain of datasources. This ensures accurate migration state tracking, particularly in multi-datasource configurations.", + "date": "2026-02-06T11:20:14Z", + "tag": "v1.54.3", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.54.3" + }, + { + "body": "# Release v1.54.2\r\n\r\n## 🚀 Enhancement\r\n\r\n### 🔹 Smart HTTP Server Activation\r\nGoFr now intelligently manages its internal server lifecycle, conditionally booting the HTTP stack only when relevant components are registered.\r\n- **Resource Efficiency**: Drastically reduces memory and CPU overhead for gRPC-only services or background workers by keeping dormant server components inactive.\r\n- **Automated Discovery**: Dynamically identifies the need for an HTTP server based on registered routes, static files, or custom handlers.\r\n- **Streamlined Footprint**: Prevents unnecessary port occupancy and improves application startup time for specialized services.\r\n\r\n## 🛠️ Fixes\r\n\r\n- **Panic Prevention in DB Metrics**: Added essential nil checks in the database operations logic to prevent potential panics during telemetry collection.\r\n\r\n- **Migration Version Chaining**: Fixed the chaining logic for fetching the last migration version to ensure consistency across complex deployments using multiple datasources.\r\n\r\n- **Docker Compose Port Mappings**: Resolved incorrect port assignments for Redis and MySQL in the `http-server` example, streamlining the local development environment.\r\n", + "date": "2026-01-31T13:45:05Z", + "tag": "v1.54.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.54.2" + }, + { + "body": "# Release v1.54.1\r\n\r\n## 🚀 Features\r\n\r\n### 🔹 gRPC Authentication Middleware\r\nIntroduced comprehensive authentication support for gRPC services, bringing it on par with HTTP services.\r\n- **Supported Methods**: Basic Authentication, API Key Authentication, and OAuth.\r\n- **Seamless Integration**: Easily enable authentication for gRPC unary and streaming handlers.\r\n- **Unified Auth Interface**: Leverages the existing authentication logic for consistency across protocols. Refer : \r\n\r\n### 🔹 Standard OTEL Tracing for gRPC\r\nEnabled standard OpenTelemetry tracing for gRPC services.\r\n- **Automatic Instrumentation**: Automatically captures spans for gRPC requests and responses.\r\n- **Better Observability**: Provides detailed insights into gRPC service performance and call chains.\r\n\r\n## 🛠️ Fixes\r\n\r\n### 🔹 EventHub Consumer Group Fix\r\n- Resolved an issue where consumer groups were not being correctly interpreted in the EventHub datasource, ensuring reliable message consumption.\r\n", + "date": "2026-01-27T05:43:56Z", + "tag": "v1.54.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.54.1" + }, + { + "body": "# **v1.54.0**\r\n\r\n## :rocket: Features\r\n\r\n:small_blue_diamond: **Server-Side Rate Limiter Middleware**\r\n\r\nGoFr now includes a built-in **Rate Limiter Middleware** to protect your APIs from abuse and ensure fair resource distribution.\r\n- **Token Bucket Algorithm**: Implements smooth rate limiting with configurable burst capacity.\r\n- **Per-IP Rate Limiting**: Support for independent limits per client IP with trusted proxy support (`X-Forwarded-For`, `X-Real-IP`).\r\n- **Observability**: Automatically tracks rate limit violations with the `app_http_rate_limit_exceeded_total` metric.\r\n- **Exemptions**: Built-in health check endpoints (`/.well-known/alive`, `/.well-known/health`) are automatically exempt.\r\n\r\n**Usage Example**\r\n```go\r\n app.UseMiddleware(middleware.RateLimiter(middleware.RateLimiterConfig{\r\n RequestsPerSecond: 10,\r\n Burst: 20,\r\n PerIP: true,\r\n }, app.Metrics()))\r\n```\r\n\r\n## 🛠️ Fixes\r\n\r\n:small_blue_diamond: **Circuit Breaker & Health Check Refinement**\r\n\r\nImproved the reliability of the Circuit Breaker and Health Check mechanisms:\r\n- **Custom Health Endpoints**: Fixed an issue where custom health endpoints were not consistently used by the circuit breaker for recovery checks.\r\n", + "date": "2026-01-18T07:02:33Z", + "tag": "v1.54.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.54.0" + }, + { + "body": "# **Release v1.53.0**\r\n\r\n## 🚀 Features\r\n\r\n🔹 **Amazon SQS PubSub Support**\r\n\r\nGoFr now supports **Amazon SQS** as a messaging backend, enabling seamless integration with AWS Simple Queue Service for building resilient, distributed microservices.\r\n\r\n- Supports both **Publishing** and **Subscribing** to SQS standard queues\r\n- **Configurable Behavior**:\r\n - Support for custom message attributes\r\n - Configurable visibility timeouts and wait times\r\n - Support for standard queues\r\n\r\n#### **Usage Example**\r\n\r\nTo use Amazon SQS, import the driver and add it to your application:\r\n\r\n```go\r\nimport (\r\n \"gofr.dev/pkg/gofr\"\r\n \"gofr.dev/pkg/gofr/datasource/pubsub/sqs\"\r\n)\r\n\r\nfunc main() {\r\n app := gofr.New()\r\n\r\n app.AddPubSub(sqs.New(&sqs.Config{\r\n Region: \"us-east-1\",\r\n AccessKeyID: \"your-access-key-id\", // optional if using IAM roles\r\n SecretAccessKey: \"your-secret-access-key\", // optional if using IAM roles\r\n // Endpoint: \"http://localhost:4566\", // optional: for LocalStack\r\n }))\r\n\r\n app.Subscribe(\"my-queue\", func(ctx *gofr.Context) error {\r\n // Process message\r\n return nil\r\n })\r\n\r\n app.Run()\r\n}\r\n```\r\n\r\n## 🚀 Enhancements\r\n\r\n🔹 **Metrics for HTTP Service Resilience**\r\n\r\nEnhanced observability for inter-service communication by adding dedicated metrics for resilience patterns.\r\n- New metric `app_http_retry_count`: Tracks the total number of retries performed for each downstream service\r\n- New metric `app_http_circuit_breaker_state`: A gauge tracking the current state (0 for Closed, 1 for Open) of the circuit breaker\r\n- **Updated Grafana Dashboards**: Included new panels to visualize retry events and circuit breaker transitions, providing immediate insights into service stability and failure patterns. You can refer : https://github.com/gofr-dev/gofr/tree/main/examples/http-server/docker/provisioning/dashboards/gofr-dashboard\r\n\r\n🔹 **Configurable Metrics Server**\r\n\r\nAdded the ability to **disable the internal metrics server** by setting the `METRICS_PORT` environment variable to `0`. This provides greater flexibility for users who prefer to handle metrics collection through external agents or in environments where a separate metrics port is not required.\r\n\r\n## 🛠️ Fixes\r\n\r\n🔹 **Zip Slip Vulnerability Protection**\r\n\r\nImproved the security of the `file/zip` package by implementing protection against **Zip Slip** (path traversal) attacks.\r\n- Automatically validates file paths during extraction to ensure they remain within the target directory\r\n- Rejects zip entries containing absolute paths or parent directory traversal sequences (`..`)\r\n- Ensures safe handling of compressed files from untrusted sources\r\n", + "date": "2026-01-10T10:03:16Z", + "tag": "v1.53.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.53.0" + }, + { + "body": "# **Release v1.52.0**\r\n\r\n## 🚀 Features\r\n\r\n🔹 **Redis PubSub Support**\r\n\r\nGoFr now supports **Redis PubSub** as a messaging backend, providing seamless integration with Redis for publish-subscribe patterns in microservices.\r\n\r\n- Supports both **Redis Channels** (traditional PubSub) and **Redis Streams** modes\r\n- Configurable via `REDIS_PUBSUB_MODE` environment variable (defaults to `streams`)\r\n- **Redis Streams** features:\r\n - Consumer groups for load balancing and message distribution\r\n - Automatic consumer group creation with `MKSTREAM` support\r\n - Configurable PEL (Pending Entry List) ratio for balancing pending vs new messages (default: 0.7, i.e., 70% PEL, 30% new messages)\r\n - Stream length management with `MaxLen` configuration\r\n - Automatic message acknowledgment handling\r\n- **Redis Channels** features:\r\n - Traditional PubSub channel support for simple messaging patterns\r\n - Automatic channel creation on first publish/subscribe\r\n- Separate database support via `REDIS_PUBSUB_DB` to prevent keyspace collisions (defaults to database 15)\r\n- Configurable buffer size, query timeout, and query limits\r\n- Automatic connection monitoring and resubscription on reconnection\r\n- Full observability with metrics, logging, and distributed tracing\r\n- Graceful error handling with permanent failure detection\r\n\r\n---\r\n\r\n## 🚀 Enhancements\r\n\r\n🔹 **HTTP Router Path Normalization**\r\n\r\nRouter now **normalizes paths before routing** to handle edge cases with double slashes and malformed paths.\r\n\r\n- Automatically cleans and normalizes request paths using `path.Clean()`\r\n- Handles empty paths, double slashes, and trailing slashes consistently\r\n- Ensures proper routing behavior regardless of path formatting in requests\r\n- Improves compatibility with various HTTP clients and reverse proxies\r\n\r\n---\r\n\r\n## 🛠️ Fixes\r\n\r\n🔹 **JSON Encoding Error Handling for NaN Values**\r\n\r\nFixed a bug where `math.NaN()` values in responses caused incorrect error handling. The responder now properly handles JSON encoding failures by:\r\n\r\n- Detecting encoding errors before writing response headers\r\n- Returning appropriate `500 Internal Server Error` status code for encoding failures\r\n\r\n🔹 **Grafana Dashboard Configuration**\r\n\r\nFixed Grafana dashboard configuration to ensure proper metrics visualization and monitoring capabilities.", + "date": "2026-01-02T13:45:04Z", + "tag": "v1.52.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.52.0" + }, + { + "body": "# Release v1.51.0\r\n\r\n## 🚀 Features\r\n\r\n### 🔐 Role-Based Access Control (RBAC)\r\n\r\nGoFr introduces a **config-driven RBAC middleware** for enforcing authorization across HTTP APIs without adding role or permission logic inside handlers.\r\n\r\n---\r\n\r\n### Key Highlights\r\n\r\n* Authorization defined entirely via **JSON/YAML configuration**\r\n* **Permission-based model**\r\n\r\n * Roles define permissions\r\n * Endpoints require permissions\r\n* **Header-based and JWT-based role extraction**\r\n\r\n * JWT-based RBAC supported via GoFr OAuth\r\n * JWT takes precedence when both are configured\r\n* **Role inheritance** support\r\n* **Exact permission matching** (no wildcards)\r\n* **Gorilla/mux-compatible route matching**\r\n\r\n * Supports path variables and constraints\r\n* **Safe-by-default enforcement**\r\n\r\n * Only routes defined in RBAC config are enforced\r\n\r\n---\r\n\r\n### Usage\r\n\r\nEnable RBAC using default config paths:\r\n\r\n```go\r\napp := gofr.New()\r\napp.EnableRBAC()\r\n```\r\n\r\nOr specify a custom RBAC config file:\r\n\r\n```go\r\napp.EnableRBAC(\"configs/rbac.json\")\r\n```\r\n\r\n---\r\n\r\n### JWT Integration\r\n\r\nRBAC integrates with GoFr OAuth for JWT-based authorization:\r\n\r\n```go\r\napp.EnableOAuth(\"https://auth.example.com/.well-known/jwks.json\", 10)\r\napp.EnableRBAC(\"configs/rbac.json\")\r\n```\r\n\r\nRoles are extracted from JWT claims using configurable claim paths.\r\n\r\n---\r\n\r\n### Observability\r\n\r\n* Debug logs include route matching and authorization decision details.\r\n* **Roles are excluded** from traces to avoid PII leakage.\r\n\r\n\r\n📚 **Documentation**\r\nRefer to the RBAC documentation for configuration details and advanced usage.\r\n", + "date": "2025-12-27T10:02:47Z", + "tag": "v1.51.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.51.0" + }, + { + "body": "# **Release v1.50.2**\r\n\r\n## 🚀 Enhancements\r\n\r\n🔹 **HTTP Connection Pool Configuration**\r\n\r\nGoFr now supports **configurable HTTP connection pool settings** to optimize performance for high-frequency HTTP requests in microservices.\r\n\r\nNew `ConnectionPoolConfig` option for `AddHTTPService()` method\r\n\r\nConfigurable settings:\r\n\r\n- `MaxIdleConns`: Maximum idle connections across all hosts (default: 100)\r\n- `MaxIdleConnsPerHost`: Maximum idle connections per host (default: 2, recommended: 10-20)\r\n- `IdleConnTimeout`: Connection keep-alive duration (default: 90 seconds)\r\n- Addresses the limitation where Go's default `MaxIdleConnsPerHost: 2` is insufficient for microservices\r\n- **Important**: `ConnectionPoolConfig` must be applied first when using multiple options \r\n\r\n\r\n🔹 **OpenTSDB Metrics Support**\r\n\r\nAdded metrics instrumentation for OpenTSDB operations to provide better observability.\r\n\r\nNew metrics:\r\n- `app_opentsdb_operation_duration`: Duration of OpenTSDB operations in milliseconds\r\n- `app_opentsdb_operation_total`: Total OpenTSDB operations\r\n- Enables monitoring and alerting on OpenTSDB data operations\r\n\r\n---\r\n \r\n\r\n## 🛠️ Fixes\r\n\r\n🔹 **Panic Recovery for OnStart Hooks**\r\nAdded panic recovery mechanism for `OnStart` hooks to prevent entire application crash. If a hook panics, the error is logged and the application continues with other hooks, improving application stability and resilience.\r\n\r\n🔹 **GCS Provider Name for Observability**\r\nAdded provider name \"GCS\" to Google Cloud Storage file store for improved logging and metrics identification. Previously it used common logging semantics \"COMMON\" shared across file storage providers leading to improper visibilty of the underlying file storage being used,\r\n\r\n🔹 **Zipkin Trace Exporter Error Handling**\r\nFixed error logging for successful trace exports (2xx status codes). Zipkin exporter now correctly ignores `201` status codes and other `2xx` responses, reducing noise in error logs for successful operations.", + "date": "2025-12-21T17:05:13Z", + "tag": "v1.50.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.50.2" + }, + { + "body": "# **Release v1.50.1**\r\n\r\n## 🚀 Enhancements\r\n\r\n🔹 **TLS / SSL Support for Database Connections**\r\n\r\nGoFr now supports **secure TLS/SSL connections** for relational databases(MySQL / MariaDB/PostgreSQL), improving security and compliance for production deployments.\r\n\r\n- New configuration `DB_SSL_MODE` with supported modes:\r\n \r\n - `disable`, `preferred`, `require`, `skip-verify`, `verify-ca`, `verify-full`\r\n \r\n- New environment variables for TLS configuration:\r\n \r\n - `DB_TLS_CA_CERT`\r\n \r\n - `DB_TLS_CLIENT_CERT`\r\n \r\n - `DB_TLS_CLIENT_KEY`\r\n \r\n- `verify-ca` and `verify-full` modes enforce **CA certificate validation**\r\n \r\n- **Mutual TLS (mTLS)** supported via client certificate & key\r\n- Refer [Documentation : Tracing In GoFr](https://gofr.dev/docs/quick-start/observability#tracing) for more info.\r\n----------\r\n\r\n🔹 **Custom Authentication Headers for Tracing Exporters**\r\n\r\nGoFr now allows configuring **custom authentication headers** for OpenTelemetry exporters, enabling better compatibility with hosted observability platforms.\r\n\r\nKey Highlights:\r\n\r\n- New configuration: `TRACER_HEADERS`\r\n \r\n - Accepts **comma-separated key=value pairs**\r\n \r\n - Example: `X-Api-Key=secret,Authorization=Bearer token`\r\n \r\n- `TRACER_HEADERS` takes priority over the existing `TRACER_AUTH_KEY`\r\n- Refer [Documentation : Connecting MySQL](https://gofr.dev/docs/quick-start/connecting-mysql) for more info.\r\n\r\n## 🛠️ Fixes\r\n\r\n🔹 **Mock HTTP Services Deduplication in Tests**\r\n\r\nFixed an issue where registering multiple mock HTTP services could result in **deduplication**, causing missing mocks and lost expectations during tests.\r\n\r\nFix Details:\r\n\r\n- Each service registered via `WithMockHTTPService(...)` now receives a **distinct mock instance**\r\n \r\n- Expectations must be set per service using: `mocks.HTTPServices[\"serviceName\"]`\r\n \r\n- Refer [Documentation : Testing in GoFr](https://gofr.dev/docs/references/testing) for more info.", + "date": "2025-12-14T13:55:15Z", + "tag": "v1.50.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.50.1" + }, + { + "body": "# **Release v1.50.0**\r\n\r\n## 🚀Features\r\n\r\n🔹 **Azure File Storage Support — New File-Store Provider**\r\n\r\nGoFr now introduces **native Azure File Storage integration** through a new provider at \r\n`gofr.dev/pkg/gofr/datasource/file/azure`.\r\n\r\nKey Highlights:\r\n\r\n- Supports configuration via **AccountName**, **AccountKey**, and **ShareName** (optional: **Endpoint**)\r\n- Automatic **connection retry loop** with connection-status logging\r\n- **Native directory support** — `Chdir`, `ReadDir`, and `Stat` behave like a real filesystem\r\n- **Automatic parent-directory creation** for nested file paths\r\n- Built-in **content-type detection** based on extension (`json`, `txt`, `csv`, `xml`, `html`, `pdf`, etc.)\r\n- One file share **per file-store instance** (explicitly documented)\r\n- Complete documentation & examples added under [Official File Handling in GoFr Documentation](https://gofr.dev/docs/advanced-guide/handling-file/page.md)\r\n\r\n### **Example**\r\n\r\n```go\r\n// Create Azure File Storage filesystem\r\nfs, err := azure.New(&azure.Config{\r\n AccountName: \"mystorageaccount\",\r\n AccountKey: \"myaccountkey\",\r\n ShareName: \"myshare\",\r\n // Endpoint is optional, defaults to https://{AccountName}.file.core.windows.net\r\n // Endpoint: \"https://custom-endpoint.file.core.windows.net\",\r\n})\r\n\r\nif err != nil {\r\n app.Logger().Fatalf(\"Failed to initialize Azure File Storage: %v\", err)\r\n}\r\n\r\napp.AddFileStore(fs)\r\n\r\napp.Run()\r\n```\r\n\r\n🔹 **CLI Improvements**\r\n\r\n- More helpful `ErrCommandNotFound` message showing the **invalid command entered**\r\n- Better help formatting with **aligned command–description columns**\r\n- Enhanced behavior for no-command scenarios: prints help + clearer messaging if added.\r\n \r\n\r\n\r\n## Bug Fixes \r\n\r\n- **Basic Auth Header Normalization**\r\nAuthorization header now correctly uses **\"Basic \"** instead of **\"basic \"** adhering to RFC standard for Basic Authorization Headers.", + "date": "2025-12-06T07:16:16Z", + "tag": "v1.50.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.50.0" + }, + { + "body": "# **Release v1.49.0**\r\n\r\n## 🚀 New Features\r\n\r\n🔹 **DB Resolver for MySQL Read/Write Splitting**\r\n\r\nGoFr introduces a powerful, production-ready **DBResolver** module that enables automatic **read/write splitting** between a primary database and multiple replicas.\r\n\r\n**Key Highlights:**\r\n\r\n* Automatic routing based on **HTTP methods**:\r\n\r\n * Writes (`POST`, `PUT`, `PATCH`, `DELETE`) → **Primary**\r\n * Reads (`GET`, `HEAD`, `OPTIONS`) → **Replicas**\r\n* Route-based overrides using `PrimaryRoutes` for strongly consistent paths\r\n* Pluggable read-balancing strategies:\r\n\r\n * **Round-robin**\r\n * **Random**\r\n* Built-in **circuit breaker** for tracking replica failures & recovery\r\n* Full integration through `dbresolver.InitDBResolver()`\r\n* Unlocks **horizontal scaling** for read-heavy services\r\n* Significantly reduces read latency\r\n* Ensures high resilience with automatic failover to primary when replicas are down\r\n\r\n**Additional Details:**\r\n\r\n**Installation**\r\n\r\n```bash\r\ngo get gofr.dev/pkg/gofr/datasource/dbresolver@latest\r\n```\r\n\r\n**Initializing DBResolver**\r\n\r\n```go\r\nimport (\r\n \"gofr.dev/pkg/gofr\"\r\n \"gofr.dev/pkg/gofr/datasource/dbresolver\"\r\n)\r\n\r\nfunc main() {\r\n a := gofr.New()\r\n\r\n err := dbresolver.InitDBResolver(a, &dbresolver.Config{\r\n Strategy: dbresolver.StrategyRoundRobin,\r\n ReadFallback: true, // fallback to primary if all replicas fail\r\n MaxFailures: 3, // mark replica down after 3 failures\r\n TimeoutSec: 30, // cooldown before retrying\r\n PrimaryRoutes: []string{\r\n \"/admin\",\r\n \"/api/payments/*\",\r\n },\r\n Replicas: []dbresolver.ReplicaCredential{\r\n {Host: \"localhost:3307\", User: \"replica_user1\", Password: \"pass1\"},\r\n {Host: \"replica2.example.com:3308\", User: \"replica_user2\", Password: \"pass2\"},\r\n {Host: \"replica3.example.com:3309\", User: \"replica_user3\", Password: \"pass3\"},\r\n },\r\n })\r\n\r\n if err != nil {\r\n a.Logger().Errorf(\"failed to initialize db resolver: %v\", err)\r\n }\r\n\r\n a.Run()\r\n}\r\n```\r\n\r\n**Read Endpoint (Auto → Replica)**\r\n\r\n```go\r\na.GET(\"/customers\", func(c *gofr.Context) (any, error) {\r\n var out []Customer\r\n c.SQL.Select(c, &out, \"SELECT id, name FROM customers\")\r\n return out, nil\r\n})\r\n```\r\n\r\n**Write Endpoint (Auto → Primary)**\r\n\r\n```go\r\na.POST(\"/customers\", func(c *gofr.Context) (any, error) {\r\n var cust Customer\r\n c.Bind(&cust)\r\n\r\n _, err := c.SQL.Exec(\"INSERT INTO customers (name) VALUES (?)\", cust.Name)\r\n return cust, err\r\n})\r\n```\r\n\r\n**Forced Primary Route**\r\n\r\n```go\r\na.GET(\"/admin/customers\", func(c *gofr.Context) (any, error) {\r\n var out []Customer\r\n c.SQL.Select(c, &out, \"SELECT id, name FROM customers\")\r\n return out, nil\r\n})\r\n```\r\n\r\n\r\n🔹 **XML Responses (response.XML)**\r\n\r\nGoFr now supports **raw XML responses** without JSON encoding by using `response.XML`.\r\n\r\n**Key Highlights:**\r\n\r\n* Writes raw XML bytes directly to the client\r\n* Default `Content-Type = application/xml`\r\n* Perfect for legacy and enterprise XML-based systems\r\n\r\n**Example:**\r\n\r\n```go\r\napp.GET(\"/legacy/xml\", func(ctx *gofr.Context) (any, error) {\r\n content := []byte(`Hello`)\r\n return response.XML{Content: content}, nil\r\n})\r\n```\r\n\r\n**XML Output**\r\n\r\n```xml\r\nHello\r\n```\r\n\r\n## 📦 Improvements\r\n\r\n🔹 **Responder Improvements**\r\n\r\n* Special response types (`Raw`, `File`, `Template`, `XML`, `Redirect`) now follow a unified handling flow\r\n* Avoids incorrect `206 Partial Content` responses\r\n* Ensures default JSON `Content-Type`\r\n\r\n🔹 **DBResolver Pooling Controls**\r\n\r\nReplica pools now scale relative to primary pools. Defaults:\r\n\r\n* Primary: `DB_MAX_IDLE_CONNECTION=2` → Replicas default to `8`\r\n* Primary: `DB_MAX_OPEN_CONNECTION=20` → Replicas default to `40`\r\n\r\nOptional overrides:\r\n\r\n```env\r\nDB_REPLICA_MAX_IDLE_CAP=100\r\nDB_REPLICA_MIN_IDLE=5\r\nDB_REPLICA_DEFAULT_IDLE=15\r\nDB_REPLICA_MAX_OPEN_CAP=500\r\nDB_REPLICA_MIN_OPEN=20\r\nDB_REPLICA_DEFAULT_OPEN=150\r\n```\r\n\r\n## 🐛 Bug Fixes & Small Changes\r\n\r\n🔹 **Authentication Timing Attack Protection**\r\n\r\n* API Key and Basic Auth now use consistent time comparisons\r\n\r\n\r\nRefer : **GoFr Official Documentation**\r\n[https://gofr.dev/docs](https://gofr.dev/docs)", + "date": "2025-11-28T16:14:37Z", + "tag": "v1.49.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.49.0" + }, + { + "body": "# **Release v1.48.0**\r\n\r\n## 🚀 New Features\r\n\r\n🔹 **Unified Token-Bucket Rate Limiter for HTTP Clients**\r\n\r\nGoFr introduces a brand-new, pluggable **rate limiter** that works across all HTTP client calls.\r\n\r\nKey Highlights:\r\n- Supports **in-memory** and **Redis-backed** stores\r\n- Simple drop-in integration via `RateLimiterConfig` or `AddOption`\r\n- Integer-only token bucket with **burst** support\r\n- Background cleanup for local buckets\r\n- Customizable request grouping using `KeyFunc`\r\n \r\n\r\nWhy this matters:\r\n- Ensures **consistent throttling** across all downstream HTTP services\r\n- Distributed apps can now safely rate-limit using **Redis**\r\n \r\n\r\nAdditional Details :\r\n- Default limit: **60 req/min**, burst **10**\r\n- Returns **RateLimitError (429)** with `RetryAfter` for easy handling.\r\n \r\n\r\n## 📦 Improvements\r\n\r\n🔹 **HTTP Client Enhancements with Rate Limiting**\r\n\r\n- Rate limiter now acts as an **HTTP wrapper**, intercepting all Get/Post/Put/Delete calls (including header variants)\r\n \r\n- Service key normalization improved via default keying (`scheme://host`)\r\n \r\n- Cleaner validation through `RateLimiterConfig.Validate()` with automatic sane defaults\r\n \r\n\r\n🔹 **SQL Operation Normalization**\r\n\r\n- SQL operation detection now always returns **UPPERCASE** keywords. Improves reliability for middleware and query inspection logic.\r\n \r\n\r\n🔹 **OAuth Token URL Validation Cleanup**\r\n\r\n- Switched to **shared scheme constants** (`http` / `https`). Reduces duplicated literals and improves code clarity\r\n\r\n\r\n## 🐛 Bug Fixes & Small Changes\r\n\r\n🔹 **Consistent SQL Operation Detection**\r\n\r\n- `getOperationType()` now normalizes to **uppercase**, preventing case-sensitivity issues across modules\r\n \r\n\r\n🔹 **Documentation Updates**\r\n\r\n- **HTTP communication guide** adds all details to add rate-limiter in your registered HTTP Services. Added examples for:\r\n - In-memory usage\r\n - Redis-backed multi-instance usage\r\n - Custom keying functions\r\n- Added Documentation to setup gRPC Streaming Services/Clients using GoFr.\r\n\r\nRefer : [GoFr Official Documentation](https://gofr.dev/docs)", + "date": "2025-11-21T17:36:33Z", + "tag": "v1.48.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.48.0" + }, + { + "body": "# **Release v1.47.1**\r\n\r\n## 📊 Enhancements\r\n\r\n🔹 **Unified Datasource Histogram Buckets**\r\n\r\nGoFr now uses a shared `getDefaultDatasourceBuckets()` across **SQL**, **Redis**, and other datasources.\r\nBenefits:\r\n\r\n- Standardized buckets from **0.05ms → 30s** \r\n- Consistent observability across datasources\r\n- Improved monitoring fidelity in Prometheus/Grafana\r\n- Easier cross-datasource latency comparison\r\n \r\n\r\n🔹 **ArangoDB v2.1.6 Compatibility & API Upgrade**\r\n\r\nUpdated GoFr’s ArangoDB datasource to align with the latest `github.com/arangodb/go-driver/v2 v2.1.6` driver. This upgrade ensures smooth integration with modern ArangoDB clusters and removes legacy API inconsistencies.\r\n\r\nKey Highlights:\r\n\r\n- Migrated collection creation to **CreateCollectionV2** / **CreateCollectionWithOptionsV2**\r\n- Ensures correct handling of **edge** and **document** collection types\r\n\r\n\r\n## 🛠️ Bug Fixes\r\n\r\n### **ArangoDB Database Creation – No More False Failures**\r\n\r\nPreviously, calling `CreateDatabase()` on an existing DB caused unnecessary user-visible errors.\r\nFix Summary:\r\n\r\n- Added an existence check before creating databases\r\n- Prevents duplicate-create errors\r\n- Ensures smooth provisioning flows during app startup or migrations\r\n \r\n### **ArangoDB Collection Type Handling Corrected**\r\n\r\nEdge collections were previously misconfigured due to missing or incorrect Type assignment.\r\nFix Summary - \r\n- Explicit `Type` handling added for **edge vs document** collections\r\n- Ensures correct metadata and relationship behavior\r\n- Updated tests to validate collection-type correctness", + "date": "2025-11-18T11:46:54Z", + "tag": "v1.47.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.47.1" + }, + { + "body": "# Release v1.47.0\r\n\r\n## ✨ Features \r\n\r\n#### 🔹 GCS File System Integration \r\n\r\nIntroduced **Google Cloud Storage (GCS) File System** as a new implementation of the GoFr `FileSystem` interface. This enables seamless integration with GCS while maintaining consistent behavior across existing backends like S3, FTP, and SFTP.\r\n\r\n**Supported Methods:**\r\n\r\n```go\r\ntype FileSystem interface {\r\n Create(name string) (File, error)\r\n Mkdir(name string, perm os.FileMode) error\r\n MkdirAll(path string, perm os.FileMode) error\r\n Open(name string) (File, error)\r\n OpenFile(name string, flag int, perm os.FileMode) (File, error)\r\n Remove(name string) error\r\n RemoveAll(path string) error\r\n Rename(oldname string, newname string) error\r\n ReadDir(dir string) ([]FileInfo, error)\r\n Stat(name string) (FileInfo, error)\r\n ChDir(dirname string) error\r\n Getwd() (string, error)\r\n}\r\n```\r\n- Consistent and unified interface for GCS, S3, FTP, and SFTP file operations.\r\n- Plug-and-play compatibility with GoFr’s file abstraction layer.\r\n- Production-ready with proper error wrapping, retries, and structured logging.\r\n- Simplifies backend switching without changing application logic.\r\n \r\n\r\nFor detailed usage, visit 👉 [GoFr Docs — GCS File System](https://gofr.dev/docs/advanced-guide/handling-file)\r\n\r\n----------\r\n\r\n### 🛠️ Bug Fixes\r\n\r\n#### Remote Logger — Improper JSON Log Formatting\r\nPreviously, ANSI color codes and non-ASCII characters appeared in JSON logs, breaking downstream log parsers.\r\n\r\n**Example of affected log output:**\r\n\r\n```json\r\n{\"level\":\"DEBUG\",\"time\":\"2025-09-17T17:54:30.625115633Z\",\"message\":\"\\u001b[38;5;8m5460fd91feac021fd633b5989abdeb26 \\u001b[38;5;34m200 \\u001b[0m 5855\\u001b[38;5;8mµs\\u001b[0m GET https://myurl\",\"gofrVersion\":\"v1.45.0\"}\r\n\r\n```\r\n\r\n**Fix Summary:**\r\n\r\n- Removed ANSI color codes and non-ASCII characters from JSON logs.\r\n- Preserved terminal log colors for local debugging.\r\n- Ensured all remote JSON logs are now ASCII-safe and parseable by log processors (ELK, Loki, Cloud Logging, etc.).\r\n \r\n", + "date": "2025-11-07T16:56:09Z", + "tag": "v1.47.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.47.0" + }, + { + "body": "# Release v1.46.3\r\n\r\n\r\n## Enhancements\r\n\r\n### **Custom Content-Type Support**: \r\nGoFr now allows respective custom content types in HTTP responses and only sets it as JSON when not explicitly present. This enhancement provides developers with greater flexibility in controlling response formats, enabling support for various content types like XML, plain text, or custom formats while maintaining JSON as the sensible default.\r\n\r\n## Fixes\r\n\r\n- **Fixed Remote Log Level Fatal Exit Issue**: Resolved a critical bug where changing to fatal level at remote log level was causing the application to exit unexpectedly. This fix ensures that remote logging operations no longer trigger unintended application termination, improving stability and reliability in production environments.", + "date": "2025-10-17T14:17:15Z", + "tag": "v1.46.3", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.46.3" + }, + { + "body": "## Release v1.46.2\r\n\r\n**GoFr core package now has 81% test coverage!** 🎉 \r\nThis milestone boosts stability, reliability, and makes contributions safer and easier.\r\n\r\n- Faster CI and more maintainable code\r\n \r\n- 🔜 Upcoming: CLI to make your life easier.\r\n \r\n\r\n**GoFr — Opinionated, Performant, Observable** https://gofr.dev\r\n\r\n \r\n", + "date": "2025-10-10T14:25:33Z", + "tag": "v1.46.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.46.2" + }, + { + "body": "## Release v1.46.1\r\n\r\n\r\n### 🚀 Enhanced Telemetry Service\r\n\r\nWe’ve enhanced GoFr’s **telemetry** to provide better insights into framework usage and runtime behavior. This improvement enables more accurate tracking of key runtime data to help us optimize performance and stability in future releases.\r\n\r\nTelemetry is **enabled by default** and can be disabled anytime by setting:\r\n\r\n```bash\r\nexport GOFR_TELEMETRY=false\r\n```\r\n \r\n", + "date": "2025-10-07T06:25:18Z", + "tag": "v1.46.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.46.1" + }, + { + "body": "## Release v1.46.0\r\n\r\n### ✨ Features\r\n\r\n🔹 **OracleDB Migration Support**\r\n\r\n- Added **OracleDB migrations with transaction support**.\r\n- Enables safe schema evolution with **begin/commit/rollback** semantics for Oracle-specific migrations.\r\n \r\n\r\n### 🛠️ Bug Fixes\r\n\r\n- **Custom Metrics Naming with OpenTelemetry**\r\nPreviously, all custom metrics were forced to include a `_total` suffix, causing incorrect or duplicate metric names due to internal upgradation of OTEL Package. Now, Metrics can be defined without the mandatory suffix and behave as originally intended.\r\n \r\n\r\n- **EventHub Subscription Fix**\r\nPreviously, EventHub subscribers were unable to consume events published in the system. Now, Subscribers can successfully receive and process published events.\r\n\r\n### ✨ Developer Experience\r\n\r\n- **Docker Setup for HTTP Server Example**\r\nImproved the **Docker setup** for the demo `http-server`. You can now explore and run it easily at: \r\n 👉 [`gofr/examples/http-server`](https://github.com/gofr-dev/gofr/tree/development/examples/http-server)\r\n \r\n", + "date": "2025-09-26T17:10:55Z", + "tag": "v1.46.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.46.0" + }, + { + "body": "## Release v1.45.0\r\n\r\n### ✨ Features\r\n\r\n🔹 **DynamoDB Key-Value Store Support**\r\n\r\n- Added full **DynamoDB support** as a GoFr KVStore implementation. \r\n- Features include: health checks, connection lifecycle management, JSON helper utilities, structured logging, OpenTelemetry tracing, and mock support for testing.\r\n \r\n - Import the gofr's external driver for DynamoDB:\r\n\t\t```shell=\r\n\t\tgo get gofr.dev/pkg/gofr/datasource/kv-store/dynamodb@latest\r\n\t\t```\r\n\t\t**How to use DynamoDB in GoFr**:\r\n\r\n\t\t```go\r\n\t\tdb := dynamodb.New(dynamodb.Configs{\r\n\t\t Table: \"gofr-kv-store\",\r\n\t\t Region: \"us-east-1\",\r\n\t\t Endpoint: \"http://localhost:8000\", // For local dev\r\n\t\t PartitionKeyName: \"pk\",\r\n\t\t})\r\n\t\t```\r\n\r\n\t\tFor full documentation, checkout 👉 [gofr.dev/docs](https://gofr.dev/docs)", + "date": "2025-09-12T14:01:09Z", + "tag": "v1.45.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.45.0" + }, + { + "body": "# Release v1.44.2\r\n\r\n## 🚀 Enhancements\r\n\r\n### 🔹 Go Version Update\r\n\r\n- Upgraded **Go to v1.25.0** across all modules and workflows.\r\n \r\n\r\n### 🔹 Remote Logger Optimization\r\n\r\n- Remote Logger produced excessive logs and wasn’t thread-safe. As an enhancement now all the successive remote logger calls will automatically shift to debug, reducing log noise.\r\n\r\n## 🛠️ Bug Fixes\r\n\r\n- ### Config Loading System\r\n\r\nPreviously, File-based configs overwrote system environment variables. Now, System env vars always take precedence, with refactored loading logic and better error handling.\r\n \r\n\r\n- ### WebSocket Implementation\r\nPreviously, context retrieval was unreliable, methods weren’t fully thread-safe, and errors like _broken pipe_ caused crashes. This has been fixed. Websocket has context-based connection handling, thread-safe methods (Read/Write/Deadline), improved error handling, concurrency-safe tests, and cleaner startup/shutdown.\r\n", + "date": "2025-09-08T14:14:25Z", + "tag": "v1.44.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.44.2" + }, + { + "body": "# Release v1.441.\r\n\r\n## 🚀 Enhancement\r\n\r\n### 🔹 Client Cancellation Handling \r\n\r\n- GoFr now returns **HTTP 499 “Client Closed Request”** when a request is canceled (`context.Canceled`) and logs it at **ERROR** level.\r\n\r\n\r\n## 🛠️ Fixes\r\n\r\n- ### Request Timeout Handling \r\n\r\n Previously, `500` status codes were received for context errors. GoFr now correctly returns **HTTP 504 “Gateway Timeout”** when a request exceeds its deadline (`context.DeadlineExceeded`) and logs it at **ERROR** level.\r\n\r\n\r\n \r\n", + "date": "2025-09-01T11:00:58Z", + "tag": "v1.44.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.44.1" + }, + { + "body": "# v1.44.0\r\n\r\n## 🚀 Features\r\n\r\n### 🔹 Correlation ID Access in GoFr Context\r\n\r\nGoFr now allows users to easily **access the correlation ID** via `gofr.Context`.\r\n\r\n- Retrieve correlation ID anywhere in your application using:\r\n \r\n ```go\r\n ctx.GetCorrelationID()\r\n ```\r\n----------\r\n\r\n### 🔹 Couchbase Support\r\n\r\nGoFr now supports injecting **Couchbase** as a datasource. Any driver implementing the following interface can be added via `app.AddCouchbase()` and accessed across the application using `gofr.Context`.\r\n\r\n#### 🧩 Supported Couchbase Interface:\r\n\r\n```go\r\ntype Couchbase interface {\r\n Get(ctx context.Context, key string, result any) error\r\n Insert(ctx context.Context, key string, document, result any) error\r\n Upsert(ctx context.Context, key string, document any, result any) error\r\n Remove(ctx context.Context, key string) error\r\n Query(ctx context.Context, statement string, params map[string]any, result any) error\r\n AnalyticsQuery(ctx context.Context, statement string, params map[string]any, result any) error\r\n}\r\n\r\n```\r\n\r\n#### ✅ Example Usage:\r\n\r\n```go\r\na := gofr.New()\r\n\r\na.AddCouchbase(couchbase.New(&couchbase.Config{\r\n Host: \"localhost\",\r\n User: \"Administrator\",\r\n Password: \"password\",\r\n Bucket: \"test-bucket\",\r\n}))\r\n\r\n```\r\n\r\n📚 **Documentation**: [Couchbase Setup Guide](https://gofr.dev/docs)\r\n\r\n----------\r\n\r\n### 🔹 OracleDB Support\r\n\r\nGoFr now supports injecting **OracleDB** as a relational datasource via a clean and extensible interface. \r\n\r\n#### 🧩 Supported Oracle Interface:\r\n\r\n```go\r\ntype Oracle interface {\r\n Exec(ctx context.Context, query string, args ...any) error\r\n Select(ctx context.Context, dest any, query string, args ...any) error\r\n}\r\n```\r\n\r\nThis approach makes it easy to inject any compatible Oracle driver while maintaining flexibility to use multiple databases within your GoFr application.\r\n \r\n\r\n#### ✅ Example – Add OracleDB in GoFr\r\n\r\n```go\r\napp.AddOracle(oracle.New(oracle.Config{\r\n Host: \"localhost\",\r\n Port: 1521,\r\n Username: \"system\",\r\n Password: \"YourPasswordHere\",\r\n Service: \"FREEPDB1\",\r\n}))\r\n```\r\n\r\n📚 **Documentation & Setup Guide**: [Oracle](https://gofr.dev/docs)\r\n\r\n----------\r\n\r\n## 🛠️ Fixes\r\n\r\n- Removed the **unnecessary SQL initialization** when no `DB_*` environment variables are defined. Prevents failure logs: `connection to failed: host name is empty`\r\n- Fixed issue where metrics showed **infinite DB calls** for every query.", + "date": "2025-08-21T12:40:56Z", + "tag": "v1.44.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.44.0" + }, + { + "body": "## v1.43.0\r\n\r\n### 🚀 Features\r\n\r\n1. **Startup Hooks Support (`OnStart`)**\r\n \r\nGoFr now allows registering **synchronous startup jobs** using the `OnStart` method.\r\n\r\nThis enables actions like:\r\n\r\n- Warming up Redis or in-memory caches\r\n \r\n- Seeding databases\r\n \r\n- Validating configuration before traffic is served\r\n \r\nThe method receives a fully initialized `*gofr.Context` with access to SQL, Redis, and Logger instances. If any hook fails, the app will **gracefully shut down** with clear logs.\r\n\r\n🛠️ **Example usage:**\r\n\r\n```go\r\na.OnStart(func(ctx *gofr.Context) error {\r\n return ctx.Redis.Set(ctx, \"key\", \"value\", 0).Err()\r\n})\r\n```\r\n\r\nThis ensures critical setup steps are completed **before your app starts accepting traffic**.\r\n\r\n\r\n### 🛠️ Fixes\r\n\r\n1. **PubSub Migrator Chain Fix**\r\n \r\nPreviously incorrect migration state visibility was seen when PubSub was connected. This has been resolved. Now it retrieves correct version from PubSub and continues chain to next migrator. Handles query failures without skipping downstream migrators\r\n \r\n", + "date": "2025-08-05T16:05:43Z", + "tag": "v1.43.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.43.0" + }, + { + "body": "# v1.42.5 \r\n\r\n## 🚀 Enhancements\r\n\r\n### 🔹 ScyllaDB Migrator Support\r\n\r\nGoFr now includes native support for **ScyllaDB** migrations.\r\n\r\n#### 🧩 Supported Migration Interface:\r\n```go\r\ntype ScyllaDB interface {\r\n Query(dest any, stmt string, values ...any) error\r\n QueryWithCtx(ctx context.Context, dest any, stmt string, values ...any) error\r\n\r\n Exec(stmt string, values ...any) error\r\n ExecWithCtx(ctx context.Context, stmt string, values ...any) error\r\n\r\n ExecCAS(dest any, stmt string, values ...any) (bool, error)\r\n\r\n NewBatch(name string, batchType int) error\r\n NewBatchWithCtx(ctx context.Context, name string, batchType int) error\r\n\r\n BatchQuery(name, stmt string, values ...any) error\r\n BatchQueryWithCtx(ctx context.Context, name, stmt string, values ...any) error\r\n\r\n ExecuteBatchWithCtx(ctx context.Context, name string) error\r\n}\r\n```\r\n\r\n\r\n### 🔹 OpenTSDB Migrator Support\r\n\r\nSupport for **OpenTSDB** migration operations, enable you to pre-seed metrics and manage annotations.\r\n\r\n#### ✅ Key Features:\r\n- Versioned JSON-based migration files\r\n \r\n- Integrated directly into GoFr's migration interface\r\n \r\n\r\n#### 🧩 Supported Migration Interface:\r\n\r\n```go\r\ntype OpenTSDB interface {\r\n // PutDataPoints can be used for seeding initial metrics during migration\r\n PutDataPoints(ctx context.Context, data any, queryParam string, res any) error\r\n\r\n // PostAnnotation creates or updates an annotation in OpenTSDB using the 'POST /api/annotation' endpoint.\r\n PostAnnotation(ctx context.Context, annotation any, res any) error\r\n\r\n // PutAnnotation creates or replaces an annotation in OpenTSDB using the 'PUT /api/annotation' endpoint.\r\n PutAnnotation(ctx context.Context, annotation any, res any) error\r\n\r\n // DeleteAnnotation removes an annotation from OpenTSDB using the 'DELETE /api/annotation' endpoint.\r\n DeleteAnnotation(ctx context.Context, annotation any, res any) error\r\n}\r\n```\r\n\r\n----------\r\n\r\n📚 **Documentation** \r\nSee [gofr.dev/migrations](https://gofr.dev/migrations) for full examples, best practices, and schema layouts for ScyllaDB and OpenTSDB migrations.\r\n", + "date": "2025-08-01T11:01:15Z", + "tag": "v1.42.5", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.42.5" + }, + { + "body": "## **v1.42.4**\r\n\r\n### **🛠️ Improvements**\r\n\r\n1. **Elasticsearch Migrator for Versioned Changes**\r\n\r\n GoFr now includes a dedicated **Elasticsearch migrator** under `pkg/migration` for managing version-controlled changes like index creation, mapping updates, and analyzer definitions.\r\n **Key Features:**\r\n\r\n * Seamless integration with GoFr’s internal **migrator interface**.\r\n * Uses Elasticsearch’s **REST API** for all operations.\r\n * Maintains migration state for reliable deployments.\r\n\r\n Refer to [gofr.dev/migrations](https://gofr.dev/docs/advanced-guide/handling-data-migrations) for more details and examples.\r\n\r\n### **🐞 Bug Fixes**\r\n\r\n1. **Fixed Panic in Context Logging in GoFr CMD Apps**\r\n\r\n A bug that caused a panic when using `ctx.Warnf` instead of `ctx.Logger.Warnf` has been fixed.\r\n\r\n **Behavior Before:**\r\n \r\n Calling `ctx.Warnf` in GoFr CMD Apps resulted in:\r\n\r\n ```\r\n panic: runtime error: invalid memory address or nil pointer dereference\r\n ```\r\n\r\n **Now:**\r\n \r\n `ctx.Warnf` functions correctly and logs without causing runtime crashes.", + "date": "2025-07-25T14:19:51Z", + "tag": "v1.42.4", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.42.4" + }, + { + "body": "# v1.42.3 \r\n\r\n----------------------\r\n\r\n## 🛡️ Security Fix\r\n- Resolved weak RSA key generation in `mock_oauth_server.go`.\r\n- Previously, a 1024-bit RSA key was being generated in the mock OAuth server (rsa.GenerateKey).\r\n- Increased the key size to 2048 bits, aligning with modern cryptographic standards and addressing [CodeQL alert #73](https://github.com/gofr-dev/gofr/security/code-scanning/73).\r\n\r\n", + "date": "2025-07-09T07:29:40Z", + "tag": "v1.42.3", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.42.3" + }, + { + "body": "## v1.42.2\r\n\r\n### 🛠️ Improvements\r\n\r\n#### 1. **Versioned Migrations Support Extended to NATS and EventHub**\r\n\r\nFollowing up on versioned migration support for Kafka, MQTT, and Google PubSub in the previous release, GoFr now officially adds:\r\n\r\n- **NATS**\r\n- **Azure EventHub**\r\n\r\nBoth now support **versioned migrations**, allowing event streaming systems to be schema-evolvable and compatible with data migration needs.\r\n\r\n#### 2. **Cleaner AuthConfig APIs for External Services**\r\n\r\nYou can now configure external services like `catfact.ninja` using streamlined constructors:\r\n\r\n**Old Way:**\r\n\r\n```go\r\napp.AddHTTPService(\"cat-facts\", \"https://catfact.ninja\",\r\n &service.APIKeyConfig{APIKey: \"some-random-key\"},\r\n &service.BasicAuthConfig{UserName: \"gofr\", Password: \"gofr\"})\r\n``` \r\n\r\n**New Way:**\r\n\r\n```go\r\napp.AddHTTPService(\"cat-facts\", \"https://catfact.ninja\",\r\n service.NewAPIKeyConfig(\"some-random-key\"),\r\n service.NewBasicAuthConfig(\"username\", \"password\"),\r\n )\r\n``` \r\n\r\n `NewBasicAuthConfig(username, password)`:\r\n\r\n- Trims values \r\n- Validates presence of both fields \r\n- Ensures **password is base64 encoded**, preventing unsafe plaintext usage \r\n- Returns **clear errors** for invalid formats\r\n \r\n\r\n `NewAPIKeyConfig(apiKey)`:\r\n\r\n- Simplified usage \r\n- Validated internally\r\n- Adds cleaner abstraction with automatic header injection\r\n \r\n", + "date": "2025-07-04T13:59:35Z", + "tag": "v1.42.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.42.2" + }, + { + "body": "# v1.42.1\r\n\r\n## 🛠️ Improvements\r\n\r\n### 1. **`NewOAuthConfig()` for Safer OAuth Setup**\r\n\r\nGoFr now includes a dedicated constructor to validate OAuth configurations for interservice HTTP calls, ensuring secure and consistent authentication setup. Refer to the [official documentation](https://gofr.dev/docs/advanced-guide/http-authentication#adding-o-auth-authentication-to-http-services) to know more :\r\n\r\n```go\r\nNewOAuthConfig(\r\n\tclientID, // string: OAuth2 client ID (required)\r\n\tsecret, // string: OAuth2 client secret (required)\r\n\ttokenURL, // string: Token exchange endpoint (required & validated)\r\n\tscopes, // []string: Optional OAuth2 scopes\r\n\tparams, // url.Values: Optional additional endpoint parameters\r\n\tauthStyle, // oauth2.AuthStyle: Credential passing style (header/body/auto)\r\n)\r\n```\r\n\r\n#### 🔍 Why this matters:\r\n\r\n* Prevents common misconfigurations like missing `tokenURL`, which previously caused vague errors such as:\r\n\r\n ```\r\n Post \"\": unsupported protocol scheme \"\"\r\n ```\r\n* Performs validation on required fields and returns clear error messages.\r\n* Encourages safe and standardized OAuth client setup.\r\n\r\n#### ✅ Example Usage:\r\n\r\n```go\r\nconfig, err := NewOAuthConfig(\r\n\t\"my-client-id\", // clientID\r\n\t\"my-client-secret\", // secret\r\n\t\"https://provider.com/oauth/token\", // tokenURL\r\n\t[]string{\"read\", \"write\"}, // scopes\r\n\tnil, // params\r\n\toauth2.AuthStyleAutoDetect, // authStyle\r\n)\r\n\r\nif err != nil {\r\n\tlog.Fatal(err)\r\n}\r\n```\r\n\r\nRefer to the [official documentation](https://gofr.dev/docs/advanced-guide/http-authentication#adding-o-auth-authentication-to-http-services) to know more.\r\n\r\n\r\n\r\n### 2. **Configurable `AuthStyle` in OAuth**\r\n\r\nThe `AuthStyle` field in OAuth2 configuration is now configurable by the user.\r\n\r\n#### 🔧 Behavior:\r\n\r\n* Previously hardcoded to `oauth2.AuthStyleInHeader`\r\n* Now allows values such as:\r\n\r\n * `oauth2.AuthStyleAutoDetect` (default)\r\n * `oauth2.AuthStyleInHeader`\r\n * `oauth2.AuthStyleInParams`\r\n\r\nThis makes GoFr's OAuth integration more flexible and compatible with diverse OAuth providers.\r\n\r\n---\r\n\r\n### 3. **Versioned Migrations in Kafka, MQTT, and Google PubSub**\r\n\r\nGoFr now supports **versioned migrations** for the following data sources:\r\n\r\n* ✅ **Kafka**\r\n* ✅ **MQTT**\r\n* ✅ **Google PubSub**\r\n\r\n#### 🧩 Additional Config (MQTT only):\r\n\r\nTo support retained message fetching for versioned migrations in MQTT, enable:\r\n\r\n```\r\nMQTT_RETRIEVE_RETAINED=true\r\n```\r\nBy default, this is set to `false` to maintain backward compatibility. When set to true, this actually retains the latest message for each topics in the connected MQTT host, hence aiding in versioned migrations.\r\n\r\n\r\n", + "date": "2025-06-27T12:42:48Z", + "tag": "v1.42.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.42.1" + }, + { + "body": "# v1.42.0\r\n\r\n## 🚀 Features\r\n\r\n### 1. **CockroachDB Support**\r\n\r\nGoFr now supports **CockroachDB**, a distributed cloud-native SQL database.\r\nDevelopers can now configure GoFr services to connect to CockroachDB using simple environment variables.\r\n\r\n#### 🔧 Configuration:\r\n```\r\nDB_DIALECT=cockroachdb\r\nDB_HOST=localhost\r\nDB_PORT=26257\r\nDB_USER=root\r\nDB_PASSWORD=your-password\r\nDB_NAME=defaultdb\r\nDB_SSL_MODE=require\r\n``` \r\nFor more details, refer to the [SQL usage guide](/advanced-guide/dealing-with-sql/).\r\n\r\n## 🛠️ Improvements\r\n\r\n### 1. **gRPC Reflection Toggle via Config**\r\n\r\nGoFr now supports enabling/disabling **gRPC server reflection** using a simple config flag:\r\n```\r\nGRPC_ENABLE_REFLECTION=true\r\n``` \r\n\r\n#### 🔍 When to enable:\r\n\r\n- **Development & Debugging**: Use with tools like grpcurl, Postman, or Evans.\r\n \r\n- **Internal Networks**: Safe in private, trusted environments.\r\n \r\n- **CI/CD Pipelines**: Ideal for service discovery in automated setups.\r\n \r\n\r\nThis allows dynamic inspection of gRPC services while maintaining control over exposure.\r\n\r\n\r\n## 🛠️ Fixes\r\n\r\n### 1. **Supabase Healthcheck Issue Resolved**\r\n\r\nResolved an issue where Supabase-backed services were not responding properly to health checks due to incorrect handling of internal pings.\r\n\r\n\r\n### 2. **Fixed Data Race in Metrics Gauges**\r\n\r\nAddressed a **concurrency bug** where the internal `float64Gauge` map was accessed without synchronization. Proper locking is now in place around map access to avoid data races during concurrent `SetGauge` and metric reads.\r\n\r\n### 3. **App Name & Version Initialization Bug**\r\n\r\nFixed a configuration issue where `AppName` and `AppVersion` were incorrectly defaulting to `gofr-app` and `dev`, even when explicitly provided by the user. These values now correctly reflect user-specified configuration during startup.\r\n", + "date": "2025-06-20T04:50:59Z", + "tag": "v1.42.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.42.0" + }, + { + "body": "# v1.41.0\r\n\r\n## 🔧 Improvements\r\n\r\n\r\n### 1. **New HTTP Error Type: `ErrorRecordNotFound`**\r\n\r\nA new standardized error type `http.ErrorRecordNotFound` has been introduced to gracefully handle scenarios where **no records are found** in the database.\r\n\r\n#### Example:\r\n\r\n```go\r\nreturn nil, http.ErrorRecordNotFound{\r\n Message: \"User not found with the given ID\",\r\n}\r\n```\r\n\r\nThis improves semantic clarity and enables better client-side handling for empty-query results.\r\n\r\n### 2. **Improved Cron Job Observability**\r\n\r\nAll **cron jobs** in GoFr now come with **built-in logger and tracing support**.\r\n\r\n- Logs from scheduled tasks are now clearly visible.\r\n \r\n- Each recurring job run is automatically **tagged with a unique trace ID**, making it easier to trace, debug, and monitor scheduled executions across your system.\r\n \r\n\r\nThis ensures better observability for background tasks without requiring additional instrumentation.\r\n\r\n## 🐛 Fixes\r\n\r\n### 1. **Supabase Connection Issue Resolved**\r\n\r\nPreviously, **Supabase connections were not initializing correctly** in GoFr due to a missing dialect registration. Supabase-backed services will now **connect without issues**—no manual fixes required.\r\n", + "date": "2025-06-12T18:05:20Z", + "tag": "v1.41.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.41.0" + }, + { + "body": "# v1.40.1\r\n\r\n\r\n## 🔧 Dependency Updates\r\n\r\nUpgraded all externalized datasource dependencies to their latest stable versions for improved performance, security, and compatibility across supported services.\r\n", + "date": "2025-06-06T06:26:14Z", + "tag": "v1.40.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.40.1" + }, + { + "body": "\r\n# v1.40.0\r\n\r\n## 🚀 Features\r\n\r\n### **Support for Supabase Database**\r\n\r\nUsers can now connect their GoFr services to a **Supabase** database using environment variables. This feature supports both **direct** and **pooled** connections, enabling secure and scalable Postgres usage via Supabase.\r\n\r\n#### 🔧 Environment Variable Setup:\r\n```bash\r\nDB_DIALECT=supabase\r\nDB_HOST=db.[PROJECT_REF].supabase.co # Optional, derived from PROJECT_REF\r\nDB_USER=postgres # Or database user name\r\nDB_PASSWORD=password\r\nDB_NAME=postgres # Or your database name\r\nDB_PORT=5432 # Optional, defaults based on connection type\r\nDB_SSL_MODE=require # Optional, forced to \"require\" for Supabase\r\n\r\n# Supabase-specific configs\r\nSUPABASE_PROJECT_REF=your_project_ref\r\nSUPABASE_CONNECTION_TYPE=direct # Options: direct, session, transaction\r\nSUPABASE_REGION=us-east-1 # Required for pooled connections\r\n\r\n# Alternatively, can provide full connection string\r\nDATABASE_URL=postgresql://postgres:password@db.your_project_ref.supabase.co:5432/postgres\r\n``` \r\n\r\n----\r\n\r\n### **Inter-Service WebSocket Communication**\r\n\r\nGoFr now supports **Inter-Service WebSocket Communication**, enabling services to exchange real-time messages over WebSocket connections. Ideal for microservices needing live updates or event-driven communication.\r\n\r\n#### 🔑 Key Methods:\r\n\r\n- `AddWSService`: Register a persistent WebSocket connection to another service with optional auto-reconnect.\r\n \r\n- `WriteMessageToService`: Send messages to any registered service.\r\n \r\n\r\n#### ✅ Example Usage:\r\n\r\n```go\r\nfunc main(){\r\n\r\n\tapp := gofr.New()\r\n\r\n\terr := app.AddWSService(\"notification-service\", \"ws://notifications.example.com/ws\", nil, true, 5*time.Second) \r\n\tif err != nil {\r\n\t app.Logger.Errorf(\"Failed to add WebSocket service: %v\", err) \r\n\t return \r\n\t}\r\n\r\n\tapp.POST(\"/send-notification\", func(ctx *gofr.Context) (any, error) {\r\n\t message := map[string]string{ \r\n\t\t \"title\": \"New Message\", \r\n\t\t \"content\": \t\"You have a new notification!\",\r\n\t }\r\n\r\n\t err := ctx.WriteMessageToService(\"notification-service\", message)\r\n\t if err != nil { \r\n\t\t return nil, err\r\n\t } \r\n\t \r\n\t\treturn \"Notification sent successfully!\", nil \r\n\t\t})\r\n\r\n\tapp.Run()\r\n}\r\n``` \r\n\r\nThis enables resilient, real-time service communication with minimal configuration.\r\n\r\n\r\n## 🔧 Improvements\r\n\r\n### 1. **New HTTP Error Type: `ServiceUnavailable`**\r\n\r\nA new standardized error type `ErrorServiceUnavailable` has been introduced for representing service unavailability due to dependency issues like database failures or third-party service outages.\r\n\r\n#### ⚙️ Use Case Example:\r\n\r\n```go\r\nerr := http.ErrorServiceUnavailable{\r\n Dependency: \"PostgreSQL\",\r\n ErrorMessage: \"Connection timeout\",\r\n}\r\n``` \r\nThis improvement enhances observability and clarity when dealing with critical external failures.\r\n", + "date": "2025-05-23T12:07:26Z", + "tag": "v1.40.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.40.0" + }, + { + "body": "# v1.39.1\r\n\r\n## 🛠 Improvements\r\n\r\n1. **Disable Logs for Health & Alive Probes**\r\n\r\n\tLogging for health check routes (`/.well-known/health` and `/.well-known/alive`) can now be disabled to reduce log clutter in environments with frequent probe calls (e.g., Kubernetes).\r\n\r\n\tSet the following environment variable:\r\n\r\n\t```bash\r\n\tLOG_DISABLE_PROBES=true\r\n\t```\r\n\r\n2. **TraceID Now Included in Context-Based Logging**\r\n\r\n\tLogs emitted using `ctx.Logger()` now automatically include the request `traceID`. This enhances traceability across services and allows easier debugging in distributed systems.\r\n\r\n\tExample log before:\r\n\r\n\t```json\r\n\t{\"message\": \"User created\", \"level\": \"INFO\"}\r\n\t```\r\n\r\n\tAfter:\r\n\r\n\t```json\r\n\t{\"message\": \"User created\", \"trace_id\": \"3ac9f5e7c12e...\", \"level\": \"INFO\"}\r\n\t```\r\n\r\n\tNo additional configuration needed—this is now built-in.\r\n\r\n3. **Enhanced ArangoDB Query Options Support**\r\n\r\n\tYou can now pass advanced query and subquery options when executing AQL queries via GoFr’s ArangoDB client.\r\n\r\n\t```go\r\n\toptions := map[string]any{\r\n\t \"count\": true,\r\n\t \"batchSize\": 100,\r\n\t \"options\": map[string]any{\r\n\t \"fullCount\": true,\r\n\t \"profile\": 2,\r\n\t },\r\n\t}\r\n\t```\r\n\r\n\tSupported keys include (but are not limited to):\r\n\r\n\t- **QueryOptions:**\r\n\r\n\t\t* `count`, `batchSize`, `ttl`, `cache`, `memoryLimit`\r\n\r\n\t- **QuerySubOptions (under `options` key):**\r\n\r\n\t\t* `fullCount`, `allowRetry`, `stream`, `optimizer`, `profile`, `maxRuntime`, `skipInaccessibleCollections`, and more\r\n\r\n\t**Example usage:**\r\n\r\n\t```go\r\n\terr := ctx.ArangoDB.Query(ctx, \"myDatabase\", query, bindVars, &results, options)\r\n\t```\r\n\r\n\tThis update gives you full control over AQL query execution for performance tuning, streaming, profiling, and more. \r\n", + "date": "2025-05-15T12:56:14Z", + "tag": "v1.39.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.39.1" + }, + { + "body": "# v1.39.0\r\n\r\n## 🚀 Features\r\n\r\n### gRPC Streaming Support \r\nGoFr now supports all gRPC streaming types, unlocking full duplex communication capabilities:\r\n- **Server-side streaming** \r\n- **Client-side streaming** c\r\n- **Bidirectional streaming** \r\nAuto-generated handlers for streaming methods with built-in metrics and tracing support for all streaming calls\r\n\r\n> **Note:** Requires `gofr-cli v0.7.0` or higher. \r\n> Refer to the [examples](https://github.com/gofr-dev/gofr/tree/main/examples/grpc-streaming) to explore usage patterns.\r\n\r\n\r\n\r\n### Redirect Support in HTTP Handlers \r\nHandlers can now trigger client redirects by returning a `response.Redirect` object:\r\n\r\n```go\r\nimport (\r\n \"gofr.dev/pkg/gofr\"\r\n \"gofr.dev/pkg/gofr/http/response\"\r\n)\r\n\r\nfunc main() {\r\n app := gofr.New()\r\n\r\n app.GET(\"/old-page\", func(ctx *gofr.Context) (any, error) {\r\n return response.Redirect{URL: \"https://example.com/new-page\"}, nil\r\n })\r\n\r\n app.Run()\r\n}\r\n```\r\nUse this for SEO-friendly permanent or temporary redirects from legacy URLs.\r\n\r\n## 🛠 Improvements\r\n\r\n### 1. TLS Support for Redis\r\n\r\nRedis connections in GoFr can now be secured using TLS. This enhancement enables secure communication in production and enterprise deployments. Configuration is done via environment variables:\r\n\r\n| Environment Variable | Description |\r\n| ------------------------ | --------------------------------------------------------------- |\r\n| `REDIS_TLS_ENABLED` | Set to `\"true\"` to enable TLS support |\r\n| `REDIS_TLS_CA_CERT_PATH` | File path to the CA certificate to verify Redis server identity |\r\n| `REDIS_TLS_CERT_PATH` | File path to the client certificate (for mTLS connections) |\r\n| `REDIS_TLS_KEY_PATH` | File path to the client private key (for mTLS connections) |\r\n\r\n\r\n\r\n\r\n", + "date": "2025-05-08T16:19:25Z", + "tag": "v1.39.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.39.0" + }, + { + "body": "# **Release - v1.38.0**\r\n\r\n## 🚀 **Features**\r\n\r\n### **Elasticsearch Integration Support**\r\n\r\n- GoFr now supports **Elasticsearch** as a pluggable data source with a standard interface for document indexing, searching, and cluster management.\r\n \r\n- Developers can inject any compatible Elasticsearch client that implements the following interface:\r\n \r\n ```go\r\n type Elasticsearch interface {\r\n Connect()\r\n CreateIndex(ctx context.Context, index string, settings map[string]any) error \r\n DeleteIndex(ctx context.Context, index string) error \r\n IndexDocument(ctx context.Context, index, id string, document any) error \r\n GetDocument(ctx context.Context, index, id string) (map[string]any, error)\r\n UpdateDocument(ctx context.Context, index, id string, update map[string]any) error \r\n DeleteDocument(ctx context.Context, index, id string) error \r\n Search(ctx context.Context, indices []string, query map[string]any) (map[string]any, error)\r\n Bulk(ctx context.Context, operations []map[string]any) (map[string]any, error)\r\n HealthChecker\r\n }\r\n ``` \r\n \r\n- Official GoFr-compatible driver is available via:\r\n \r\n ```\r\n go get gofr.dev/pkg/gofr/datasource/elasticsearch@latest\r\n ```\r\n \r\n- Example usage in your `main.go`:\r\n \r\n ```go\r\n func main (){\r\n\t\t app := gofr.New()\r\n\t\t \r\n\t\t\tes := elasticsearch.New(elasticsearch.Config{\r\n\t\t Addresses: []string{\"http://localhost:9200\"},\r\n\t\t Username: \"elastic\",\r\n\t\t Password: \"changeme\",\r\n\t\t })\r\n \r\n\t\t app.AddElasticsearch(es)\r\n\t\t \r\n\t\t\tapp.Run ()\r\n }\r\n ``` \r\n- Checkout our [official documentation](https://gofr.dev/docs/datasources/getting-started) for more details. \r\n\r\n \r\n", + "date": "2025-04-24T15:41:51Z", + "tag": "v1.38.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.38.0" + }, + { + "body": "# **Release - v1.37.1**\r\n\r\n## 🚀 **Improvements**\r\n\r\n### **Extended Error Responses (RFC 9457-style)**\r\n\r\n- GoFr now supports extended error responses following the [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html) specification.\r\n \r\n- Developers can implement the new `ResponseMarshaler` interface to enrich error responses with custom fields beyond the standard error message and status code.\r\n\t```go\r\n\ttype ResponseMarshaler interface {\r\n\t Response() map[string]any\r\n\t}\r\n\t```\r\n- Example:\r\n\r\n\t```go\r\n\ttype ValidationError struct {\r\n\t Field string \r\n\t Message string \r\n\t Code int \r\n\t} \r\n\r\n\tfunc (e ValidationError) Error() string { \r\n\t\treturn e.Message \r\n\t} \r\n\r\n\tfunc (e ValidationError) StatusCode() int { \r\n\t\treturn e.Code \r\n\t} \r\n\r\n\tfunc (e ValidationError) Response() map[string]any { \r\n\t\treturn map[string]any{ \r\n\t\t\t\"field\": e.Field, \r\n\t\t\t\"type\": \"validation_error\", \r\n\t\t\t\"details\": \"Invalid input format\",\r\n\t }\r\n\t}\r\n\t``` \r\n\r\n\t> ⚠️ **Note:** The `message` field is automatically populated from the `Error()` method. Custom fields with the name \"message\" in the `Response()` map should not be used as they will be ignored in favor of the `Error()` value.\r\n\r\n\tThis feature allows more descriptive and structured error responses, ideal for client-side validation, API debugging, and frontend integration.\r\n\r\n## 🛠 **Fixes**\r\n\r\n\r\n### **1. WebSocket: Fixed Concurrent Write Panic**\r\n\r\n- WebSocket writes are now thread-safe. Previously, concurrent calls to `WriteMessageToSocket()` caused race conditions and panics. Writes are now internally synchronized.\r\n \r\n\r\n### **2. NATS: Synchronous Connection Setup**\r\n\r\n- NATS connections are now established synchronously to prevent `errJetStreamNotConfigured` errors when calling `jetStream()` immediately after `Connect()`.\r\n", + "date": "2025-04-16T04:13:04Z", + "tag": "v1.37.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.37.1" + }, + { + "body": "\r\n## 🚀 **Features** \r\n\r\n\r\n### **1. Dgraph Migration Support**\r\n\r\n- Added native migration capabilities for Dgraph through new methods, enabling precise schema evolution:\r\n\t```go\r\n\t// Apply or update the complete Dgraph schema \r\n\tApplySchema(ctx context.Context, schema string) error\r\n\t// Atomically create or update a field definition\r\n\tAddOrUpdateField(ctx context.Context, fieldName, fieldType, directives string) error \r\n\t// Permanently remove a field/predicate and its associated data \r\n\tDropField(ctx context.Context, fieldName string) error\t \r\n\t``` \r\n- Refer to the [official documentation](https://gofr.dev/docs/datasources/dgraph) for full usage details.\r\n \r\n## 🛠 **Improvements** \r\n\r\n\r\n### **1. gRPC Server Configuration via `AddGRPCServerOptions`**\r\n- GoFr now allows configuring advanced gRPC `ServerOptions`.\r\n- Example: Enabling TLS and setting a connection timeout\r\n \r\n ```go\r\n creds, _ := credentials.NewServerTLSFromFile(\"server-cert.pem\", \"server-key.pem\")\r\n \r\n app.AddGRPCServerOptions(\r\n grpc.Creds(creds),\r\n grpc.ConnectionTimeout(10*time.Second),\r\n )\r\n ``` \r\n- Refer to the [official documentation](https://gofr.dev/docs/advanced-guide/grpc) to know more.\r\n \r\n### **2. Add Custom Unary Interceptors**\r\n \r\n ```go\r\n app.AddGRPCUnaryInterceptors(authInterceptor)\r\n ```\r\n- GoFr already logs, traces and sends default metrics for all gRPC calls. No external interceptor for such features is necessary. Custom server-side `UnaryServerInterceptors` can now be registered easily for use cases like:\r\n \r\n - Authentication\r\n - Request validation\r\n \r\n - For guidance on how to define Server UnaryInterceptors that can be added in your GoFr's gRPC server, check out the [official documentation](https://gofr.dev/docs/advanced-guide/grpc).\r\n\r\n### **3. Advanced gRPC Client DialOptions Support**\r\n\r\n- Clients can now be customized extensively via `grpc.DialOptions`.\r\n This allows to add gRPC services with :\r\n - Secure TLS communication\r\n - Load-balanced connections\r\n - Retry logic\r\n - Context-aware metadata injection (useful for tracing and auth)\r\n \r\n\r\n ```go\r\n const serviceConfig = `{\r\n \"loadBalancingPolicy\": \"round_robin\",\r\n \"methodConfig\": [{\r\n \"name\": [{\"service\": \"HelloService\"}],\r\n \"retryPolicy\": {\r\n \"maxAttempts\": 4,\r\n \"initialBackoff\": \"0.1s\",\r\n \"maxBackoff\": \"1s\",\r\n \"backoffMultiplier\": 2.0,\r\n \"retryableStatusCodes\": [\"UNAVAILABLE\", \"RESOURCE_EXHAUSTED\"]\r\n }\r\n }]\r\n }` \r\n \r\n\t// Metadata interceptor to add client ID to each request\r\n func MetadataUnaryInterceptor(ctx context.Context, method string, req, reply any,\r\n cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption,\r\n ) error {\r\n md := metadata.Pairs(\"client-id\", \"f1b1a372-02f5-4065-9ccf-113d34a3d5ed\")\r\n \r\n ctx = metadata.NewOutgoingContext(ctx, md) \r\n\t\r\n\t return invoker(ctx, method, req, reply, cc, opts...)\r\n } \r\n\t\r\n\tfunc main() {\r\n app := gofr.New()\r\n \r\n creds, err := credentials.NewClientTLSFromFile(\"cert.pem\", \"\") if err != nil {\r\n app.Logger().Errorf(\"TLS error: %v\", err) return }\r\n \r\n grpcClient, err := client.NewHelloServiceGoFrClient(\r\n app.Config.Get(\"GRPC_SERVER_HOST\"),\r\n app.Metrics(),\r\n grpc.WithTransportCredentials(creds),\r\n grpc.WithDefaultServiceConfig(serviceConfig),\r\n grpc.WithChainUnaryInterceptor(MetadataUnaryInterceptor),\r\n ) \r\n\t\r\n\t\tif err != nil {\r\n app.Logger().Errorf(\"Failed to create client: %v\", err) return \r\n }\r\n \r\n handler := NewGreetHandler(grpcClient)\r\n \r\n app.GET(\"/hello\", handler.Hello)\r\n \r\n app.Run()\r\n }\r\n ```\r\n - Refer to the [official documentation](https://gofr.dev/docs/advanced-guide/grpc) to know more.\r\n \r\n## 🛠 **Fixes** \r\n\r\n### **1. SurrealDB `Update` Method: Unexpected Behavior Fixed** \r\n- Regardless of the input, the `Update` method previously inserted an unexpected hardcoded key-value pair. The method now correctly updates **only the intended fields** as passed by the caller.\r\n", + "date": "2025-04-08T14:29:59Z", + "tag": "v1.37.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.37.0" + }, + { + "body": "# **Release - v1.36.0** \r\n\r\n## 🚀 **Features** \r\n\r\n### **1. SurrealDB Migration Support** \r\n- Added support for database migration operations in SurrealDB. \r\n- Supported methods include: \r\n\t```go\r\n\t// Creates a new namespace in SurrealDB.\r\n\tCreateNamespace(ctx context.Context, namespace string) error \r\n\t// Creates a new database in SurrealDB.\r\n\tCreateDatabase(ctx context.Context, database string) error \r\n\t// Deletes a namespace from SurrealDB.\r\n\tDropNamespace(ctx context.Context, namespace string) error\r\n\t// Deletes a database from SurrealDB. \r\n\tDropDatabase(ctx context.Context, database string) error \r\n\t``` \r\n- Refer to our [official documentation](https://gofr.dev/docs/datasources/surrealdb) to know more.\r\n\r\n## 🛠 **Improvements** \r\n\r\n### **1. Default Metrics for SurrealDB Data Source** \r\n- Introduced default metric collection for SurrealDB at the specified `METRICS_PORT`, enabling better observability and performance monitoring. \r\n\r\n### **2. JWT Claim Validations** \r\n- `EnableOAuth` now takes an additional JWT validation options as `jwt.ParserOption`, allowing fine-grained control over claim validation. \r\n- Example :\r\n\t```go\r\n\tapp.EnableOAuth(\r\n\t\t\"http://jwks-endpoint\",\r\n\t\t20,\r\n\t\tjwt.WithExpirationRequired(), // to enforce presence of exp claim in every token\r\n\t\tjwt.WithAudience(\"https://api.example.com\"),\r\n\t\tjwt.WithIssuer(\"https://auth.example.com\")\r\n\t)\r\n\t```\r\n- To know more about the different claim validation options, check out our [official documentation](https://gofr.dev/docs/advanced-guide/http-authentication#3-o-auth-2-0).\r\n\r\n## 🛠 **Fixes** \r\n\r\n### **1. `pprof` Profiling Enhancements** \r\n- Previously, the `pprof` endpoint was restricted to being enabled only when the `APP_ENV=DEBUG` environment variable was set, and it ran on the specified `HTTP_PORT`. This prevented users from loading their different environments, for e.g. stage or production configurations if we set `APP_ENV` as `DEBUG` for profiling.\r\n- GoFr now automatically enables `pprof` profiling on `METRICS_PORT` (default: `2121`). \r\n- Profiling endpoints include : \r\n - `/debug/pprof/cmdline` \r\n - `/debug/pprof/profile` \r\n - `/debug/pprof/symbol` \r\n - `/debug/pprof/trace` \r\n - `/debug/pprof/` (index) \r\n \r\nFor more information on setting up and using profiling in your application, refer to our [official documentation](https://gofr.dev).\r\n\r\n", + "date": "2025-03-25T15:02:17Z", + "tag": "v1.36.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.36.0" + }, + { + "body": "# **Release - v1.35.2**\r\n\r\n# 🛠 **Improvements**\r\n\r\n### **1. Kafka TLS Enhancements**\r\n- Added support for configuring Kafka with **TLS parameters**, enabling seamless integration with **Confluent Kafka SaaS** and similar ecosystems.\r\n Introduced the following configuration options:\r\n\r\n ```\r\n KAFKA_TLS_CERT_FILE : Path to the TLS certificate file. \r\n KAFKA_TLS_KEY_FILE : Path to the TLS key file. \r\n KAFKA_TLS_CA_CERT_FILE : Path to the TLS CA certificate file. \r\n KAFKA_TLS_INSECURE_SKIP_VERIFY : Boolean option to skip TLS certificate verification. \r\n ```\r\n\r\n **Note:** All provided paths must be absolute. Check out our [official documentation](https://gofr.dev/docs/advanced-guide/using-publisher-subscriber#kafka) to learn more. \r\n\r\n### **2. Static File Server Enhancements**\r\n \r\n- If a requested file is missing, the server attempts to serve `404.html` with a `404` status code. If `404.html` is unavailable, it returns a `404` status code.\r\n \r\n- If the file being accessed lacks **read permissions**, the error is logged and an appropriate `500 Internal Server Error` status code and response body is returned.\r\n\r\n# 🛠 **Fixes**\r\n\r\n### **1. Middleware Execution Order**\r\n- Restored the original middleware execution order prior to [**Release v1.35.0**](https://github.com/gofr-dev/gofr/releases/tag/v1.35.0). Standard middlewares (`logs`, `traces`, `metrics`, `CORS`) are now executed before user-defined middlewares, ensuring consistent observability even when responses are handled early for e.g. in custom middlewares.\r\n- However, **WebSocket** connection upgrades necessarily take place **after all middleware processing**, maintaining compatibility with corresponding authentication flows introduced previously.\r\n\r\n\r\n### **2. Kafka Security Protocol Configuration Fix**\r\n- Previously, SASL authentication failed in ecosystems like Confluent due to missing `security.protocol` support, causing errors like: \r\n ```\r\n SASL handshake failed: EOF\r\n ```\r\n- Introduced `KAFKA_SECURITY_PROTOCOL` to explicitly define the security protocol for Kafka communication. Supported options include : `PLAINTEXT`, `SSL`, `SASL_PLAINTEXT`, `SASL_SSL`, ensuring seamless authentication. Check out [official documentation](https://gofr.dev/docs/advanced-guide/using-publisher-subscriber#kafka) to know more.\r\n \r\n### 3. **Redundant WriteHeader Calls**\r\n- Fixed redundant WriteHeader calls when custom middleware in the static file server set a status code, preventing log spam like:\r\n\t ```\r\n\t http: superfluous response.WriteHeader call from gofr.dev/pkg/gofr/http/middleware.(*StatusResponseWriter).WriteHeader (logger.go:23)\r\n\t``` \r\n- Headers are now written once—by either user-defined middleware or the framework handlers.\r\n", + "date": "2025-03-18T14:48:52Z", + "tag": "v1.35.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.35.2" + }, + { + "body": "\r\n# **Release v1.35.1**\r\n \r\n# 🛠 **Improvements**\r\n\r\n### **1. Kafka Connection & Security Enhancements**\r\n\r\n- Added support for configuring Kafka with extra **connection and security parameters** to **seamlessly integrate** with Confluent Kafka SaaS and similar platforms.\r\n- Introduced three new configuration options for **SASL authentication**:\r\n\r\n\t#### 🔧 `KAFKA_SASL_MECHANISM`\r\n\t- SASL mechanism for authentication (e.g. `PLAIN`, `SCRAM-SHA-256`, `SCRAM-SHA-512`)\r\n\t- Default: `None`\r\n\r\n\t#### 🔧 `KAFKA_SASL_USERNAME`\r\n\r\n\t- Username for SASL authentication\r\n\t- Default: `None`\r\n\r\n\t#### 🔧 `KAFKA_SASL_PASSWORD`\r\n\r\n\t- Password for SASL authentication\r\n\t- Default: `None`\r\n\r\n### **2. Multiple Static Folders Support**\r\n- **Multiple static folders** can now be registered and served at different custom endpoints.\r\n \r\n- Example usage:\r\n```go\r\n package main \r\n \r\n import \"gofr.dev/pkg/gofr\" \r\n\r\n\tfunc main() {\r\n app := gofr.New()\r\n app.AddStaticFiles(\"public\", \"./public\")\r\n app.AddStaticFiles(\"static\", \"./static\")\r\n app.Run()\r\n }\r\n ``` \r\n \r\n- In this example:\r\n \r\n - Files in the `public` folder are served at `host/public/*`\r\n - Files in the `static` folder are served at `host/static/*`\r\n \r\n### **3. ArangoDB Resource Creation Enhanced**\r\n\r\n- `CreateDB`, `CreateGraph`, and `CreateCollection` methods in Arango, now check for existing resources before creating them. Check out our [official documentation](https://gofr.dev/docs/datasources/arangodb) to know more.\r\n\r\n# 🛠 **Fixes**\r\n\r\n### **1. Fixed Static File Server Endpoint Handling**\r\n- Previously, files in the **`static`** directory were served by default at **`/static/`**. If the same directory was registered at another path, the files were being served at both endpoints, resulting in duplicate serving.\r\n- This has now been fixed. If a user registers a custom endpoint using **`app.AddStaticFiles({custom-endpoint}, ./static)`**, GoFr will automatically serve the files only at the specified custom endpoint.\r\n- Additionally, if any directories are re-registered within the GoFr application, the files will now be served at the **latest** registered endpoint, ensuring there’s no duplication.\r\n\r\n\r\n\r\n\r\n", + "date": "2025-03-11T13:34:29Z", + "tag": "v1.35.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.35.1" + }, + { + "body": "# **Release v1.35.0**\r\n\r\n# 🚀 **Features**\r\n\r\n### **1. Template Rendering Support** \r\n\r\n- GoFr now supports rendering HTML templates directly from handlers using the new `response.Template` response type. \r\n\r\n- By default, it looks for template files in the `templates` directory, automatically parsing the specified file and injecting the provided data, allowing developers to serve dynamic HTML content without requiring a separate template rendering mechanism.\r\n\r\n- #### **Usage Example:**\r\n\tHere's how you can use template rendering in a GoFr handler:\r\n\t```go\r\n\tpackage main\r\n\r\n\timport (\r\n\t\t\"fmt\"\r\n\t\t\"net/http\"\r\n\r\n\t\t\"gofr.dev/pkg/gofr\"\r\n\t\t\"gofr.dev/pkg/gofr/response\"\r\n\t)\r\n\r\n\ttype Todo struct {\r\n\t\tTitle string\r\n\t\tDescription string\r\n\t\tDone bool\r\n\t}\r\n\r\n\tfunc main() {\r\n\t\tapp := gofr.New()\r\n\r\n\t\tapp.GET(\"/todo\", func(ctx *gofr.Context) (interface{}, error) {\r\n\t\t\tdata := Todo{\r\n\t\t\t\tTitle: \"Learn GoFr\",\r\n\t\t\t\tDescription: \"Understand how template rendering works in GoFr\",\r\n\t\t\t\tDone: false,\r\n\t\t\t}\r\n\t\t\treturn response.Template{Name: \"todo.html\", Data: data}, nil\r\n\t\t})\r\n\r\n\t\tapp.Run()\r\n\r\n\t}\r\n\t```\r\n\r\n\t#### **Example Template (templates/todo.html):**\r\n\r\n\t```\r\n\t\r\n\t\r\n\t\r\n\t \r\n\t \r\n\t Todo\r\n\t\r\n\t\r\n\t

    {{ .Title }}

    \r\n\t

    {{ .Description }}

    \r\n\t

    Status: {{ if .Done }} ✅ Completed {{ else }} ❌ Pending {{ end }}

    \r\n\t\r\n\t\r\n\t```\r\n\tWhen a request is made to `/todo`, GoFr will render the `todo.html` template by injecting the provided `Todo` struct values.\r\n\r\n### **2. Graceful Shutdown Configuration**\r\n\r\n- A new environment variable, `SHUTDOWN_GRACE_PERIOD`, has been introduced to allow customization of the server's shutdown timeout.\r\n\r\n- **Default:** `30s`\r\n- **Purpose:** Ensures in-flight requests are served before shutdown.\r\n \r\n# 🛠 **Fixes & Improvements**\r\n\r\n### **1. Authentication in Websockets** \r\n- Ensured proper authentication for GoFr WebSocket connections by requiring user-defined authentication or middleware to run before upgrading, as WebSockets do not inherently support authentication.\r\n \r\n### **2. Fixed Infinite Write Retry on Closed WebSocket** \r\n- Previously, if a WebSocket connection was only writing and then closed, it would result in infinite retries without properly closing. This issue has now been resolved.\r\n\r\n\r\n", + "date": "2025-03-04T14:00:12Z", + "tag": "v1.35.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.35.0" + }, + { + "body": "# **Release - v1.34.1**\r\n\r\n\r\n# 🛠 **Fixes & Improvements**\r\n\r\n### **1. GoFr Now Runs on Go 1.24** \r\nGoFr is now powered by the latest Golang version 1.24, ensuring compatibility with the newest features and improvements. \r\n\r\n### **2. Improved Retry Mechanism for MQTT Default Client** \r\nThe MQTT Default Client now includes automatic retries and seamless reconnection, enhancing reliability and stability. \r\n\r\n### **3. Fixed Command Routing in CLI Applications** \r\nCLI applications built with GoFr now correctly resolve the intended commands typed in the terminal, preventing unintended command execution.\r\n", + "date": "2025-02-25T17:41:34Z", + "tag": "v1.34.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.34.1" + }, + { + "body": "# **Release - v1.34.0**\r\n\r\n# 🚀 **Features**\r\n\r\n### **1. NATS-KV Store Support** \r\nGoFr now supports **NATS-KV Store** as a datastore. The supported methods include:\r\n \r\n```go\r\ntype KVStore interface {\r\n Get(ctx context.Context, key string) (string, error)\r\n Set(ctx context.Context, key, value string) error\r\n Delete(ctx context.Context, key string) error\r\n HealthCheck(ctx context.Context) (any, error)\r\n}\r\n```\r\nTo integrate NATSKV Store as a datastore, add the following configuration:\r\n \r\n```go\r\napp.AddKVStore(nats.New(nats.Configs{\r\n Server: \"nats://localhost:4222\",\r\n Bucket: \"persons\",\r\n }))\r\n```\r\nRefer to the [**documentation**](https://gofr.dev/docs/advanced-guide/injecting-databases-drivers) for more details.\r\n \r\n### **2. ArangoDB Migrations** \r\nAdded migration support for **ArangoDB**, allowing users to perform schema changes seamlessly. The following methods are now available in migration:\r\n \r\n```go\r\n// CreateDB creates a new database in ArangoDB.\r\nCreateDB(ctx context.Context, database string) error\r\n\r\n// DropDB deletes an existing database in ArangoDB.\r\nDropDB(ctx context.Context, database string) error\r\n\r\n// CreateCollection creates a new collection in a database.\r\nCreateCollection(ctx context.Context, database, collection string, isEdge bool) error\r\n\r\n// DropCollection deletes an existing collection from a database.\r\nDropCollection(ctx context.Context, database, collection string) error\r\n\r\n// CreateGraph creates a new graph in a database.\r\n//\r\n// Parameters:\r\n// - ctx: Request context for tracing and cancellation.\r\n// - database: Name of the database where the graph will be created.\r\n// - graph: Name of the graph to be created.\r\n// - edgeDefinitions: Pointer to EdgeDefinition struct containing edge definitions.\r\n//\r\n// Returns an error if edgeDefinitions is not of type *EdgeDefinition or is nil.\r\nCreateGraph(ctx context.Context, database, graph string, edgeDefinitions any) error\r\n\r\n// DropGraph deletes an existing graph from a database.\r\nDropGraph(ctx context.Context, database, graph string) error\r\n\r\n``` \r\n \r\n# 🛠 **Fixes & Improvements**\r\n\r\n### **1. Automatic PubSub Reconnection** \r\nFixed automatic retries and reconnection in **PubSub**. It now reconnects immediately upon connection availability.\r\n \r\n### **2. Added `go.work`** \r\nSimplifies dependency handling and development with better multi-module management.\r\n\r\n### **3. Telemetry for Active GoFr Servers** \r\nGoFr now includes telemetry to track the number of running GoFr servers, helping us understand adoption and usage trends.\r\n\r\nTo disable telemetry, set:\r\n```bash\r\nGOFR_TELEMETRY=false\r\n```\r\n\r\n", + "date": "2025-02-18T14:30:13Z", + "tag": "v1.34.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.34.0" + }, + { + "body": "# Release v1.33.0\r\n\r\n# 🚀 **Features**\r\n\r\n### **1. ArangoDB Support as a Datasource**\r\n\r\nUsers can now integrate **ArangoDB** as a datasource within their GoFr applications. Supported Methods include : \r\n```go\r\ntype ArangoDB interface {\r\n // CreateDocument creates a new document in the specified collection.\r\n\tCreateDocument(ctx context.Context, dbName, collectionName string, document any) (string, error)\r\n\t// GetDocument retrieves a document by its ID from the specified collection.\r\n\tGetDocument(ctx context.Context, dbName, collectionName, documentID string, result any) error\r\n\t// UpdateDocument updates an existing document in the specified collection.\r\n\tUpdateDocument(ctx context.Context, dbName, collectionName, documentID string, document any) error\r\n\t// DeleteDocument deletes a document by its ID from the specified collection.\r\n\tDeleteDocument(ctx context.Context, dbName, collectionName, documentID string) error\r\n\t// GetEdges retrieves all the edge documents connected to a specific vertex in an ArangoDB graph.\r\n\tGetEdges(ctx context.Context, dbName, graphName, edgeCollection, vertexID string, resp any) error\r\n\t// Query executes an AQL query and binds the results\r\n\tQuery(ctx context.Context, dbName string, query string, bindVars map[string]any, result any) error\r\n HealthCheck(context.Context) (any, error)\r\n}\r\n```\r\nRefer to our [official documentation](https://gofr.dev/docs/advanced-guide/injecting-databases-drivers) to know more.\r\n\r\n### **2. Default HealthCheck Support for gRPC Servers and Clients**\r\nThis release introduces built-in **HealthCheck** support for both gRPC servers and clients.\r\n\r\n- **Prerequisites:** \r\nTo use the new health check features, ensure that **gofr-cli v0.5.0** is installed. Use it to generate your gRPC client and server templates.\r\n\r\n- **gRPC Servers**\r\nAfter running the existing command:\r\n\r\n\t```\r\n\t gofr wrap grpc server -proto=path/to/your/proto/file\r\n\t```\r\n\r\n\tA new file named `health_gofr.go` will be generated. This file contains the health functionality for your gRPC server. The health methods are embedded within the GoFr gRPC server struct, which looks like this:\r\n\r\n\t```go\r\n\ttype {serviceName}GoFrServer struct {\r\n\t health *healthServer\r\n\t}\r\n\t```\r\n\r\n\t**Supported HealthCheck Methods:**\r\n\r\n\t```go\r\n\t// Check checks if the service is healthy.\r\n\tfunc (h *healthServer) Check(ctx *gofr.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error)\r\n\t// Watch watches for any changes in the service’s health status.\r\n\tfunc (h *healthServer) Watch(ctx *gofr.Context, in *grpc_health_v1.HealthCheckRequest, stream grpc_health_v1.Health_WatchServer) error\r\n\t// SetServingStatus allows you to set the health status of the service (healthy, unhealthy, etc.).\r\n\tfunc (h *healthServer) SetServingStatus(ctx *gofr.Context, service string, status grpc_health_v1.HealthCheckResponse_ServingStatus)\r\n\t// Shutdown gracefully shuts down the service.\r\n\tfunc (h *healthServer) Shutdown(ctx *gofr.Context)\r\n\t// Resume resumes the service after it has been shut down.\r\n\tfunc (h *healthServer) Resume(ctx *gofr.Context)\r\n\t```\r\n\r\n\tTo integrate these health features, register your gRPC server in `main.go` as follows:\r\n\r\n\t```go\r\n\tfunc main() {\r\n\t app := gofr.New()\r\n\r\n\t packageName.Register{serviceName}ServerWithGofr(app, &{packageName}.New{serviceName}GoFrServer())\r\n\r\n\t app.Run()\r\n\t}\r\n\t```\r\n\r\n- **For gRPC Clients**\r\nHealthCheck calls are now supported on all gRPC clients generated through the gofr-cli command i.e :\r\n\t```\r\n\tgofr wrap grpc client -proto=path/to/your/proto/file\r\n\t```\r\n\t**Supported HealthCheck methods** include :\r\n\t```go\r\n\t// Check checks the service health.\r\n\tfunc (c *{serviceName}GoFrClient) Check(ctx *gofr.Context, in *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error)\r\n\t// Watch allows the client to watch for health status changes.\r\n\tfunc (c *{serviceName}GoFrClient) Watch(ctx *gofr.Context, in *grpc_health_v1.HealthCheckRequest) (grpc.ServerStreamingClient[grpc_health_v1.HealthCheckResponse], error)\r\n\t```\r\n\t\t\r\nFor a deeper understanding, check out our [official documentation](https://gofr.dev/docs/advanced-guide/grpc) and refer to our [example repo](https://github.com/gofr-dev/gofr/tree/main/examples/grpc).\r\n\r\n# 🛠️ **Fix**\r\nResolved an issue with the `AddRESTHandlers` support where PUT requests were not updating records in the database when we have `autoincrement` tag added in our entity struct. The issue has now been fixed.\r\n", + "date": "2025-02-06T06:37:38Z", + "tag": "v1.33.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.33.0" + }, + { + "body": "# Release v1.32.0\r\n\r\n## 🚀 **Features :**\r\n\r\n**1. Support for SurrealDB as a Data Source** \r\nSurrealDB is now supported as a data source in GoFr. The following methods are supported:\r\n```go\r\ntype SurrealDB interface {\r\n\tQuery(ctx context.Context, query string, vars map[string]any) ([]any, error)\r\n\tCreate(ctx context.Context, table string, data any) (map[string]any, error)\r\n\tUpdate(ctx context.Context, table string, id string, data any) (any, error)\r\n\tDelete(ctx context.Context, table string, id string) (any, error)\r\n\tSelect(ctx context.Context, table string) ([]map[string]any, error)\r\n\tHealthCheck(context.Context) (any, error)\r\n}\r\n```\r\n\r\nTo integrate SurrealDB into your application, use the `AddSurrealDB` method in your `main.go` :\r\n\r\n```go\r\nclient := surrealdb.New(&surrealdb.Config{\r\n Host: \"localhost\",\r\n Port: 8000,\r\n Username: \"root\",\r\n Password: \"root\",\r\n Namespace: \"test_namespace\",\r\n Database: \"test_database\",\r\n TLSEnabled: false,\r\n})\r\n\r\napp.AddSurrealDB(client)\r\n```\r\nFor more details, refer to our [official documentation](https://gofr.dev/docs/advanced-guide/injecting-databases-drivers).\r\n\r\n**2. Built-in Metrics for gRPC Services**\r\n \r\nGoFr now includes **in-built metrics** for all **gRPC server executions and interservice gRPC calls**. We automatically capture metrics to measure the response time of gRPC server/clients.\r\n \r\n - Prerequisites : **gofr-cli version v0.4.0** must be installed. \r\n - Use the following commands :\r\n - ` gofr wrap grpc server --proto=` to generate GoFr's gRPC handlers.\r\n - `gofr wrap grpc client -proto=` to generate GoFr's gRPC client.\r\n- Refer the [official documentation](https://gofr.dev/docs/advanced-guide/grpc) & [examples](https://github.com/gofr-dev/gofr/tree/main/examples/grpc) to set up gRPC server/clients with in built logging, tracing and metrics support.\r\n\r\n## 🛠️ **Fixes :**\r\n **1. Enhanced gRPC Logging**\r\n- Improved logs for interservice gRPC calls, now including:\r\n - **Trace ID:** For better tracking of distributed requests.\r\n - **Status Code:** Logs the response status of gRPC calls for easy debugging and issue resolution.\r\n", + "date": "2025-01-27T08:59:36Z", + "tag": "v1.32.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.32.0" + }, + { + "body": "# Release v1.31.0\r\n\r\n## 🚀 Features :\r\n\r\n1. **Support for ScyllaDB as a Data Source** \r\n ScyllaDB is now supported as a data source in GoFr. The following methods are supported:\r\n\r\n ```go\r\n Query(dest any, stmt string, values ...any) error \r\n QueryWithCtx(ctx context.Context, dest any, stmt string, values ...any) error \r\n Exec(stmt string, values ...any) error \r\n ExecWithCtx(ctx context.Context, stmt string, values ...any) error \r\n ExecCAS(dest any, stmt string, values ...any) (bool, error) \r\n NewBatch(name string, batchType int) error \r\n NewBatchWithCtx(ctx context.Context, name string, batchType int) error \r\n BatchQuery(name, stmt string, values ...any) error \r\n BatchQueryWithCtx(ctx context.Context, name, stmt string, values ...any) error \r\n ExecuteBatchWithCtx(ctx context.Context, name string) error \r\n ```\r\n\r\n To integrate ScyllaDB into your application, use the `AddScyllaDB` method:\r\n\r\n ```go\r\n client := scylladb.New(scylladb.Config{\r\n Host: app.Config.Get(\"SCYLLADB_HOST\"),\r\n Keyspace: app.Config.Get(\"SCYLLADB_KEYSPACE\"),\r\n Port: app.Config.GetInt(\"SCYLLADB_PORT\"),\r\n Username: app.Config.Get(\"SCYLLADB_USERNAME\"),\r\n Password: app.Config.Get(\"SCYLLADB_PASSWORD\"),\r\n })\r\n app.AddScyllaDB(client)\r\n ```\r\n\r\n For detailed instructions, refer to the [ScyllaDB documentation](https://github.com/gofr-dev/gofr/blob/development/docs/advanced-guide/injecting-databases-drivers/page.md#scylladb).\r\n\r\n2. **Built-in Tracing for Interservice gRPC Calls** \r\n All interservice gRPC calls in GoFr now include in-built tracing support.\r\n\r\n - **Prerequisite**: Ensure `gofr-cli` v0.3.0 is installed. To install `gofr-cli`, run:\r\n ```bash\r\n go install gofr.dev/cli/gofr@latest\r\n ```\r\n\r\n - To generate the gRPC client, run:\r\n ```bash\r\n gofr wrap grpc client -proto=path/to/your/proto/file\r\n ```\r\n\r\n For detailed instructions on setting up the gRPC Client in GoFr, refer to the [documentation](https://gofr.dev/docs/advanced-guide/grpc). You can also explore an example gRPC client implementation in the [examples folder](https://github.com/gofr-dev/gofr/tree/ca741320534061d5e4550931949e27543b6c69bf/examples/grpc).\r\n\r\n\r\n**Full Changelog**: https://github.com/gofr-dev/gofr/compare/v1.30.0...v1.31.0", + "date": "2025-01-20T11:18:30Z", + "tag": "v1.31.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.31.0" + }, + { + "body": "## Release v1.30.0\r\n\r\n## 🚀 Features\r\n\r\n#### 1. GoFr's Context Support in gRPC Handlers\r\n\r\nIntroduced context integration for gRPC handlers, enabling efficient dependency and tracing management.\r\nAutomatically generates gRPC handler templates with built-in support for `gofr's context` using the **`gofr wrap grpc`** command of [gofr cli](https://github.com/gofr-dev/gofr-cli/releases/tag/v0.2.1).\r\n\r\n**Note:** For details on setting up Protocol Buffers and gRPC in GoFr, visit the official [Documentation](https://gofr.dev/docs/advanced-guide/grpc#creating-protocol-buffers) and [Example](https://github.com/gofr-dev/gofr/tree/development/examples/grpc-server)\r\n\r\n## 🔧 Fixes\r\n\r\n#### 1. `ExpectSelect` Update in SQL Mocks\r\n\r\nRefactored the `ExpectSelect` function in SQL mocks. Users can now set expected responses using the `ReturnsResponse` method, ensuring accurate mock behavior during tests.\r\n\r\n* **Example Usage:**\r\n\r\n ```go\r\n var result, actualResult Response\r\n\r\n mockContainer, sqlMock := NewMockContainer(t)\r\n ctx := &gofr.Context{\r\n Container: mockContainer,\r\n }\r\n\r\n expectedResult := Response{\r\n // ... fill with expected values\r\n }\r\n\r\n sqlMock.ExpectSelect(ctx, &result, query).ReturnsResponse(expectedResult)\r\n\r\n ctx.SQL.Select(ctx, &actualResult, query)\r\n\r\n assert.Equal(t, actualResult, expectedResult)\r\n ```\r\n\r\n#### 2. Environment Variable Handling\r\n\r\n* OS-level environment variables now override values from `.env`, `..env` configurations, ensuring consistent behaviour across environments.\r\n\r\n#### 3. Improved Logging\r\n\r\n* Removed sensitive information (e.g., usernames and passwords) from MongoDB connection logs by replacing `uri` with `host`.\r\n* Fixed inaccurate Redis connection logs and removed unnecessary SQL connection logs when no SQL connection is established.\r\n* Added error logs for database migration failures, improving visibility during debugging.\r\n\r\n#### 4. Security Fixes\r\n\r\n* Updated `golang.org/x/crypto` to v0.31.0 to resolve potential authorization bypass issues.\r\n* Updated `go.mod` in `pkg/gofr/datasource/mongo` for compatibility with Go commands.\r\n", + "date": "2025-01-10T06:24:21Z", + "tag": "v1.30.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.30.0" + }, + { + "body": "# Release v1.29.0\r\n\r\n---\r\n\r\n### ✨ Features:\r\n1. **Custom Metadata in Responses** \r\n Users can now include metadata in API responses using the `response.Response` struct. This allows for clean, structured responses while providing additional contextual information. \r\n - **Response Structure**: \r\n - With Metadata: \r\n ```json\r\n {\r\n \"data\": {},\r\n \"metadata\": {}\r\n }\r\n ```\r\n - Without Metadata: \r\n ```json\r\n {\r\n \"data\": {}\r\n }\r\n ``` \r\n - **Example Usage**: \r\n ```go\r\n func HelloHandler(c *gofr.Context) (interface{}, error) {\r\n headers := map[string]string{\r\n \"X-Custom-Header\": \"CustomValue\",\r\n }\r\n\r\n metaData := map[string]any{\r\n \"environment\": \"staging\",\r\n \"timestamp\": time.Now(),\r\n }\r\n\r\n return response.Response{\r\n Data: map[string]string{\"message\": \"Hello, World!\"},\r\n Metadata: metaData,\r\n Headers: headers,\r\n }, nil\r\n }\r\n ``` \r\n---\r\n\r\n2. **Support for Redis Database Selection**:\r\n- Introduces a new config `REDIS_DB` to specify the Redis database index to be used.\r\n- Example usage:\r\n ```go\r\n os.Setenv(\"REDIS_DB\", \"1\")\r\n ```\r\n\r\n### 🛠️ Fixes:\r\n1. **Disconnected Spans Exported for Remote-log-url**:\r\n- Resolves an issue where disconnected spans were created for each fetch request of the remote log.\r\n- Ensures that all traces exported for a single HTTP request have spans in hierarchy.\r\n\r\n2. **Hardcoded Ports Fix**:\r\n- Addresses the issue of hardcoded ports within the codebase.\r\n- Now allows for dynamic port configuration, improving flexibility and deployment scenarios.\r\n\r\n3. **Lowercase Default Paths for CRUD Helpers**:\r\n- Changes the default paths for CRUD helpers to be in lowercase.\r\n- Helps avoid confusion caused by case sensitivity on certain servers.\r\n", + "date": "2024-12-24T13:12:45Z", + "tag": "v1.29.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.29.0" + }, + { + "body": "# Release v1.28.2\r\n\r\n**Fixes 🛠️️ :**\r\n\r\n- Set `Content-Type: application/json` for HTTP service that doesn't explicitly provide a content type, when calling `GET`, `POST`, or similar methods during interservice communication.\r\n", + "date": "2024-12-11T07:29:15Z", + "tag": "v1.28.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.28.2" + }, + { + "body": "## Release v1.28.1\r\n\r\n#### 🛠️ Fixes:\r\n\r\n1. **Improved Static File Metrics**\r\n \r\n - Metrics middleware now accurately identifies and tracks static file requests, including handling file paths with query parameters.\r\n \r\n **Example:**\r\n Metrics will now correctly log `/static/example.js` or `/static/example.js?v=42`.\r\n \r\n2. **Subscription Handler Validation**\r\n - Improved error handling in `App.Subscribe()`.\r\n - Ensures that `topic` and `handler` parameters are validated to prevent runtime errors.\r\n - Logs detailed error messages for invalid subscriptions.\r\n\r\n", + "date": "2024-12-09T08:44:34Z", + "tag": "v1.28.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.28.1" + }, + { + "body": "### ✨ Features:\r\n\r\n**Custom Response Headers Support**:\r\nUsers can add custom HTTP response headers using the `Response` struct. This feature helps add extra information, such as security policies or other metadata, to improve communication between clients and servers.\r\n- Example usage:\r\n ``` go\r\n return response.Response{\r\n Data: \"Hello World from new Server\",\r\n Headers: map[string]string{\"X-Custom-Header\": \"CustomValue\", \"X-Another-Header\": \"AnotherValue\"},\r\n }` \r\n ``` \r\n \r\n**OpenTSDB Support**: \r\nUsers can integrate OpenTSDB to store and retrieve time-series data. \r\n- Methods include:\r\n - `PutDataPoints`: Send data to OpenTSDB.\r\n - `QueryDataPoints`: Retrieve data based on specified parameters.\r\n - `GetAggregators`: Get available aggregation functions.\r\n - `QueryAnnotation`, `PostAnnotation`, `PutAnnotation`, `DeleteAnnotation`: Manage annotations in OpenTSDB.\r\n \r\n - To import GoFr's external OpenTSDB driver:\r\n `go get gofr.dev/pkg/gofr/datasource/opentsdb@latest`\r\n \r\n```go\r\ntype OpenTSDB interface { \r\n HealthChecker \r\n PutDataPoints(ctx context.Context, data any, queryParam string, res any) error\r\n QueryDataPoints(ctx context.Context, param any, res any) error \r\n QueryLatestDataPoints(ctx context.Context, param any, res any) error \r\n GetAggregators(ctx context.Context, res any) error QueryAnnotation(ctx context.Context, queryAnnoParam map[string]any, res any) error \r\n PostAnnotation(ctx context.Context, annotation any, res any) error\r\n PutAnnotation(ctx context.Context, annotation any, res any) error \r\n DeleteAnnotation(ctx context.Context, annotation any, res any) error \r\n}\r\n``` \r\n - For more info, checkout the documentation: https://gofr.dev/docs/advanced-guide/injecting-databases-drivers#open-tsdb\r\n\r\n**Support for Binding Binary/Octet Stream**: \r\nUsers can bind `binary/octet-stream` content directly to `[]byte` slices using GoFr context.\r\n- Example usage:\r\n\r\n ```go\r\n var result []byte\r\n err := req.Bind(&result)\r\n if err != nil {\r\n log.Fatalf(\"Bind error: %v\", err)\r\n } \r\n ```\r\n\r\n\r\n### 🛠️ Fixes:\r\n\r\n**Milliseconds Logged as Microseconds**:\r\n- Previously, operation duration was calculated in milliseconds but was incorrectly logged as microseconds, which led to confusion. This has been fixed to ensure that logs display the accurate duration in microseconds.\r\n \r\n**Dgraph Datasource Panic Fix**\r\n- Fixed an issue where the Dgraph datasource would panic due to an uninitialized tracer when added as an external datasource. This bug has been addressed.\r\n \r\n**Solr Methods Fixes**:\r\n- Fixed errors occurring in the following Solr datasource methods: `Update`, `Delete`, `ListFields`, `Retrieve`, `AddField`, `UpdateField`, `DeleteField`.\r\n- Updated documentation and provided a working example, accordingly.\r\n \r\n**Deprecated `UseMiddlewareWithContainer` Method**:\r\n- The method `UseMiddlewareWithContainer` has been deprecated and will be removed in future releases. Developers should use the `*App.UseMiddleware` method instead, which does not depend on the container.\r\n\r\n **Static File Path Handling Fix**:\r\n - Fixed an issue in the `AddStaticFiles` method where file paths were not correctly resolved when they didn't start with `./` or were not absolute paths. The fix ensures that the correct file path is registered for static file serving.\r\n", + "date": "2024-11-27T12:51:45Z", + "tag": "v1.28.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.28.0" + }, + { + "body": "# Release v1.27.1\r\n\r\n## 🛠️ Fixes\r\n### Fix Google Pubsub Panic\r\nThe callback function for the Google client Subscribe function was configured to fetch one message per Subscribe call. Still, at times the message was being sent to a closed channel causing unexpected behaviour. Fixed the issue of receiving messages on a channel that closes only on application shutdown.", + "date": "2024-11-17T04:50:30Z", + "tag": "v1.27.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.27.1" + }, + { + "body": "# Release v1.27.0\r\n\r\n## ✨ Features\r\n \r\n1. **`UseMiddlewareWithContainer` for Custom Middleware with Container Access** \r\n Introduced the `UseMiddlewareWithContainer` method, which allows custom middleware to access the application's container. This provides access to essential services such as logging, configuration, and database instances, enabling middleware to modify request processing dynamically.\r\n \r\n **Example Usage:**\r\n \r\n ```go\r\n import (\r\n \"fmt\"\r\n \"net/http\"\r\n \r\n \"gofr.dev/pkg/gofr\"\r\n \"gofr.dev/pkg/gofr/container\"\r\n )\r\n \r\n func main() {\r\n // Create a new GoFr application instance\r\n a := gofr.New()\r\n \r\n // Add custom middleware with container access\r\n a.UseMiddlewareWithContainer(customMiddleware)\r\n \r\n ....\r\n }\r\n \r\n // Define middleware with container access\r\n func customMiddleware(c *container.Container, handler http.Handler) http.Handler {\r\n return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\r\n c.Logger.Log(\"Hey! Welcome to GoFr\")\r\n handler.ServeHTTP(w, r)\r\n })\r\n }\r\n ` \r\n \r\n 2. **Migrations Support in MongoDB** \r\n GoFr now introduces support for data migrations in MongoDB, enabling seamless modifications to your database schema and data. This includes adding new fields, modifying data types of existing fields, setting or removing indexes, and applying constraints to collections. All changes are meticulously tracked in the GoFr Migrations Table, ensuring a reliable and auditable history of database updates.\r\n----------\r\n\r\n## 🛠️ Fixes\r\n\r\n1. **Remote Log URL Setup** \r\n Resolved an issue where logs fetched from the remote log URL were missing correlation IDs. Logs now consistently include the correlation ID, ensuring better traceability.\r\n \r\n2. **Entity DataType Documentation Update** \r\n Enhanced the documentation for the `Add-rest-handler` feature by specifying supported data types in the entity structure, improving usability and reducing confusion.\r\n \r\n3. **SQL Logs Level Adjustment** \r\n Fixed the log level for successful SQL connections, which was mistakenly set to debug. It is now appropriately logged at the info level, aligning with logging best practices.\r\n\r\n\r\n", + "date": "2024-11-15T11:33:55Z", + "tag": "v1.27.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.27.0" + }, + { + "body": "# Release v1.26.0\r\n\r\n## ✨ Features\r\n\r\n### 1. Support for NATS as External Pub-Sub\r\n\r\nWe have added support for NATS as an external pub/sub service in GoFr. Users can now easily set up NATS for message publishing and subscribing by configuring it via `app.AddPubSub`. Here’s a quick example:\r\n\r\n```go\r\napp.AddPubSub(nats.New(&nats.Config{\r\n Server: \"nats://localhost:4222\",\r\n CredsFile: \"\",\r\n Stream: nats.StreamConfig{\r\n Stream: \"my-stream\",\r\n Subjects: []string{\"order-logs\", \"products\"},\r\n },\r\n MaxWait: 5 * time.Second,\r\n MaxPullWait: 500,\r\n Consumer: \"my-consumer\",\r\n}, app.Logger()))\r\n\r\n```\r\n\r\nTo inject NATS, import it using the following command:\r\n\r\n```go\r\ngo get gofr.dev/pkg/gofr/datasources/pubsub/nats\r\n```\r\n\r\nRefer to our documentation for detailed setup instructions.\r\n\r\n### 2. New Environment Variable `DB_CHARSET`\r\n\r\nIntroduced a new environment variable `DB_CHARSET` to make the **MySQL character set configurable**. By default, DB_CHARSET is set to **utf8**. However, setting it to **utf8mb4** is recommended for full Unicode support, including emojis and special characters.\r\n\r\n### 3. Enhanced CLI with TUI Elements (Spinners and Progress Bar)\r\n\r\nThis release enhances the GoFr command-line experience by introducing Text User Interface (TUI) elements, including spinners and a progress bar for visual feedback during command execution. \r\n\r\nCheck out an example in `examples/sample-cmd` to see this in action.\r\n\r\n### 4. New Examples for Remote File Server Interaction\r\n\r\nWe’ve added new examples in the `examples/using-add-filestore` directory, demonstrating how to interact with remote file servers using GoFr. This addition provides a convenient reference for developers working with remote file management.\r\n\r\n---\r\n\r\n## 🛠️ Fixes\r\n\r\n### 1. Fix: Invalid ClickHouse Documentation\r\n\r\nUpdated the ClickHouse package documentation to highlight only the relevant parts, improving readability and maintainability.\r\n", + "date": "2024-11-07T09:14:22Z", + "tag": "v1.26.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.26.0" + }, + { + "body": "# Release v1.25.0 \r\n\r\n## ✨ Features\r\n\r\n### BadgerDB Tracing\r\n- Added context support and tracing for **BadgerDB** datasource operations, enhancing observability and tracking within the BadgerDB storage layer.(Released pkg/gofr/datasource/kv-store/badger - v0.2.0)\r\n\r\n### Redis Authentication Support\r\n- Users can now connect to Redis instances requiring a username, password, or both. Configure these credentials in the `.env` file located in the `configs` folder:\r\n\r\n - **`REDIS_USER`**: User credential for connecting to the Redis server. Multiple users with different permissions can be configured within a single Redis instance. For more details, refer to the [official Redis documentation](https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/).\r\n \r\n - **`REDIS_PASSWORD`**: Password credential required only if authentication is enabled on the Redis instance.\r\n\r\n### Enhanced Authentication Retrieval in Context\r\n- The `GetAuthInfo` method on the context provides easy access to various authentication methods, allowing developers to retrieve:\r\n\r\n - **JWT Claims**: Use `GetAuthInfo().GetClaims()` when OAuth is enabled, returning a `jwt.MapClaims` response.\r\n \r\n - **Username**: Use `GetAuthInfo().GetUsername()` for basic authentication, returning the username or an empty string if basic auth is not enabled.\r\n \r\n - **API Key**: Use `GetAuthInfo().GetAPIKey()` for API key-based authentication, returning the API key or an empty string if API key auth is not enabled.\r\n\r\n---\r\n\r\n## 🛠️ Fixes\r\n\r\n### Static File Route Issue\r\n- Resolved a bug in the `AddStaticFiles` method where static files could not be accessed via specified routes. Now, running the following code:\r\n\r\n ```go\r\n func main() {\r\n app := gofr.New()\r\n app.AddStaticFiles(\"/\", \"./static\")\r\n app.Run()\r\n }\r\n ```\r\n\r\n Files within the `./static` directory can be accessed properly, e.g., `http://localhost:9000/abc.jpeg`, without encountering a \"route not registered\" error.\r\n\r\n### Controlled Access to OpenAPI Files\r\n- Prevented direct access to the `openapi.json` file via static routes. The file is now restricted to access through explicitly defined routes such as `/.well-known/swagger` or `/.well-known/openapi.json` for secure and controlled API documentation access.\r\n", + "date": "2024-11-04T11:01:14Z", + "tag": "v1.25.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.25.0" + }, + { + "body": "# Release v1.24.2\r\n\r\n## 🛠️ Fixes\r\n- **Tracing in Solr data source**\r\nFixed missing tracing for Solr data source. Now, spans for Solr data source will be visible on the trace graph with important attributes to better debug the user application.\r\n\r\n- **Cassandra logs misaligned**\r\nThe logs while running the migrations for the Cassandra database were misaligned and did not contain the exact operation that was being performed. Now logs are aligned with the other logs and also contain which operation is being performed.\r\n\r\n- **EventHub messages not getting consumed**\r\nThe Azure EventHub was not able to subscribe to the messages, fixed the flow to correctly consume the messages, and also added proper shutdown for the subscriber to close on application closure.\r\n\r\n- **Application Shutdown not working when subscribers are registered**\r\nNow gofr applications will shutdown gracefully without getting stuck because of the forever subscription for topics.\r\n\r\n\r\n**Full Changelog**: https://github.com/gofr-dev/gofr/compare/v1.24.1...v1.24.2", + "date": "2024-10-22T12:19:59Z", + "tag": "v1.24.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.24.2" + }, + { + "body": "# Release v1.24.1\r\n\r\n## 🛠️ Fixes:\r\n- **Google Subscriptions not calling user handlers**\r\nFixed a bug in the Google subscriber where messages were being consumed in the callback handler but was not calling the `SubscribeFunc` registered by the user.", + "date": "2024-10-17T14:21:07Z", + "tag": "v1.24.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.24.1" + }, + { + "body": "# Release v1.24.0\r\n\r\n\r\n## ✨ Features:\r\n\r\n- **Cassandra Tracing & Context Support**: \r\n We’ve added context support and tracing for Cassandra operations, improving flexibility and observability. The following methods are now available:\r\n\r\n **Single Operations:**\r\n - **`QueryWithCtx`**: Executes queries with context, binding results to the specified destination.\r\n - **`ExecWithCtx`**: Executes non-query operations with context.\r\n - **`ExecCASWithCtx`**: Executes lightweight (CAS) transactions with context.\r\n - **`NewBatchWithCtx`**: Initializes a new batch operation with context.\r\n\r\n **Batch Operations:**\r\n - **`BatchQueryWithCtx`**: Adds queries to batch operations with context.\r\n - **`ExecuteBatchWithCtx`**: Executes batch operations with context.\r\n - **`ExecuteBatchCASWithCtx`**: Executes batch operations with context and returns the result.\r\n\r\n ***Note:*** The following methods in Cassandra have been deprecated:\r\n ```go\r\n type Cassandra interface {\r\n Query(dest interface{}, stmt string, values ...any) error\r\n Exec(stmt string, values ...any) error\r\n ExecCAS(dest any, stmt string, values ...any) (bool, error)\r\n BatchQuery(stmt string, values ...any) error\r\n NewBatch(name string, batchType int) error\r\n CassandraBatch\r\n }\r\n\r\n type CassandraBatch interface {\r\n BatchQuery(name, stmt string, values ...any)\r\n ExecuteBatch(name string) error\r\n ExecuteBatchCAS(name string, dest ...any) (bool, error)\r\n }\r\n ```\r\n\r\n\r\n- **JWT Claims Retrieval**: \r\n OAuth-enabled applications can now retrieve JWT claims directly within handlers. Here’s an example:\r\n ```go\r\n func HelloHandler(c *gofr.Context) (interface{}, error) {\r\n // Retrieve the JWT claim from the context\r\n claimData := c.Context.Value(middleware.JWTClaim)\r\n\r\n // Assert that the claimData is of type jwt.MapClaims\r\n claims, ok := claimData.(jwt.MapClaims)\r\n if !ok {\r\n return nil, fmt.Errorf(\"invalid claim data type\")\r\n }\r\n\r\n // Return the claims as a response\r\n return claims, nil\r\n }\r\n ```\r\n\r\n## 🛠️ Fixes:\r\n\r\n- **Redis Panic Handling**: \r\n Resolved an issue where calling `Redis.Ping()` without an active connection caused the application to panic. This is now handled gracefully.\r\n\r\n- **Docker Example Enhancement**: \r\n The `http-server` example has been enhanced to include Prometheus and Grafana containers in its Docker setup, allowing users to fully explore GoFr's observability features.\r\n", + "date": "2024-10-14T12:24:50Z", + "tag": "v1.24.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.24.0" + }, + { + "body": "# Release v1.23.0 \r\n\r\n## ✨Features:\r\n- **Tracing support added for MongoDB database:** \r\n Added tracing capabilities for MongoDB database interactions, extending built-in tracing support across various MongoDB methods.\r\n \r\n- **Support for binding encoded forms:** \r\n Added functionality for binding multipart-form data and URL-encoded form data. \r\n - You can use the `Bind` method to map form fields to struct fields by tagging them appropriately. \r\n - For more details, visit the [documentation](https://gofr.dev/docs/references/context).\r\n\r\n## 🛠️Fixes:\r\n- **Resolved nil correlationID due to uninitialized exporter:** \r\nAddressed an issue that emerged from release [v1.22.0](https://github.com/gofr-dev/gofr/releases/tag/v1.22.0), where the trace exporter and provider were not initialized when no configurations were specified. The isssue has been fixed. The trace provider is now set to initialize by default, regardless of the provided configuration.\r\n \r\n \r\n \r\n", + "date": "2024-10-07T07:24:30Z", + "tag": "v1.23.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.23.0" + }, + { + "body": "# Release v1.22.1\r\n\r\n## ✨ Fixes\r\n- Fix clickhouse Import\r\nImporting clickhouse import was failing in version 1.22.0, due to otel tracer package present as indirect dependency.", + "date": "2024-10-03T07:22:59Z", + "tag": "v1.22.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.22.1" + }, + { + "body": "# Release v1.22.0\r\n\r\n## ✨ Features\r\n- Support for tracing in clickhouse.\r\nClickhouse Traces are now added and sent along with the respective request traces.\r\n\r\n- Support for sampling traces.\r\nTraces can now be sampled based on the env config `TRACER_RATIO` \r\nIt refers to the proportion of traces that are exported through sampling. It ranges between 0 to 1. By default, this ratio is set to 1, meaning all traces are exported.\r\n\r\n- Support Azure Eventhub as external pub-sub datasource.\r\nEventhub\r\n\t- Eventhub can be used similar to how messages are published and subscribed to KAFKA, MQTT and Google Pubsub.\r\n\t- To inject Eventhub import it using the following command.\r\n\t ```\r\n\t go get gofr.dev/pkg/gofr/datasources/pubsub/eventhub\r\n\t ```\r\n - Setup Eventhub by calling the AddPubSub method of gofr.\r\n\t ```\r\n\t app.AddPubSub(eventhub.New(eventhub.Config{ \r\n\t\tConnectionString: \"\", \r\n\t\tContainerConnectionString: \"\", \r\n\t\tStorageServiceURL: \"\", \r\n\t\tStorageContainerName: \"\", \r\n\t\tEventhubName: \"\", \r\n\t\tConsumerGroup: \"\", \r\n\t\t}))\r\n\t\t```\r\n\tRefer [documentation](https://gofr.dev/docs/advanced-guide/using-publisher-subscriber) to know how to get these values.\r\n\r\n- Support to enable HTTPS in the HTTP server\r\nYou can now secure your servers with SSL/TLS certificates by adding the certificates through following configs - `CERT_FILE` and `KEY_FILE`.\r\n\r\n## ✨ Fixes\r\n- Fix SQLite logs.\r\n\tEmpty strings were coming due to difference in configuration parameters required in SQLite vs other SQL datasource when connecting which has been fixed.", + "date": "2024-10-01T11:00:45Z", + "tag": "v1.22.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.22.0" + }, + { + "body": "# Release v1.21.0\r\n\r\n## ✨ Features\r\n- ### Support for DGraph\r\n Dgraph can be added using the method on gofrApp AddDgraph.\r\n Following methods are supported:\r\n```go\r\n// Dgraph defines the methods for interacting with a Dgraph database.\r\n\r\ntype Dgraph interface {\r\n// Query executes a read-only query in the Dgraph database and returns the result.\r\nQuery(ctx context.Context, query string) (interface{}, error)\r\n\r\n// QueryWithVars executes a read-only query with variables in the Dgraph database.\r\nQueryWithVars(ctx context.Context, query string, vars map[string]string) (interface{}, error)\r\n\r\n// Mutate executes a write operation (mutation) in the Dgraph database and returns the result.\r\nMutate(ctx context.Context, mu interface{}) (interface{}, error)\r\n\r\n// Alter applies schema or other changes to the Dgraph database.\r\nAlter(ctx context.Context, op interface{}) error\r\n\r\n// NewTxn creates a new transaction (read-write) for interacting with the Dgraph database.\r\nNewTxn() interface{}\r\n\r\n// NewReadOnlyTxn creates a new read-only transaction for querying the Dgraph database.\r\nNewReadOnlyTxn() interface{}\r\n\r\n// HealthChecker checks the health of the Dgraph instance.\r\nHealthChecker\r\n}\r\n```\r\nTo use Dgraph in your GoFr application, follow the steps given below:\r\n#### Step 1\r\n`go get gofr.dev/pkg/gofr/datasource/dgraph`\r\n\r\n #### Step 2\r\n ```\r\napp.AddDgraph(dgraph.New(dgraph.Config{\r\nHost: \"localhost\",\r\nPort: \"8080\",\r\n}))\r\n```\r\nGoFr supports both queries and mutations in Dgraph. To know more: [Read the Docs](https://gofr.dev/docs/advanced-guide/injecting-databases-drivers)\r\n\r\n## 🛠 Enhancements\r\n- ### Migrations in Cassandra\r\n Users can now add migrations while using `Cassandra` as the datasource. This enhancement assumes that user has already created the `KEYSPACE` in cassandra. A `KEYSPACE` in Cassandra is a container for tables that defines data replication settings across the cluster. [Visit the Docs](https://gofr.dev/docs/advanced-guide/handling-data-migrations) to know more.\r\n\r\n```\r\ntype Cassandra interface {\r\n Exec(query string, args ...interface{}) error\r\n NewBatch(name string, batchType int) error\r\n BatchQuery(name, stmt string, values ...any) error\r\n ExecuteBatch(name string) error\r\n HealthCheck(ctx context.Context) (any, error)\r\n}\r\n```\r\nTo achieve atomicity during migrations, users can leverage batch operations using the NewBatch, BatchQuery, and ExecuteBatch methods. These methods allow multiple queries to be executed as a single atomic operation.\r\n\r\nWhen using batch operations, consider using batchType: LoggedBatch i.e. 0 for atomicity or an UnloggedBatch i.e. 1 for improved performance where atomicity isn't required. This approach provides a way to maintain data consistency during complex migrations. \r\n\r\n- ### Added mocks for Metrics \r\n `MockContainer` can be used to set expectation for metrics in the application while writing test.\r\n \r\n #### Usage:\r\n ```\r\n // GoFr's mockContainer\r\n _, mock := NewMockContainer(t) \r\n \r\n // Set mock expectations using the mocks from NewMockContainer\r\n mock.Metrics.EXPECT().IncrementCounter(context.Background(), \"name\")\r\n \r\n // Call to your function where metrics has to be mocked\r\n .\r\n .\r\n .\r\n \r\n ```\r\n", + "date": "2024-09-23T12:21:03Z", + "tag": "v1.21.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.21.0" + }, + { + "body": "# Release v1.20.0\r\n\r\n## ✨ Features\r\n- Support for Solr\r\nSolr can now be used as a datasource, for adding Solr use `AddSolr(cfg Solr.Config)` method of gofrApp.\r\nRefer [documentation](https://github.com/gofr-dev/gofr/blob/development/docs/advanced-guide/injecting-databases-drivers/page.md#solr) for detailed info.\r\nSupported Functionalities are:\r\n\t```\r\n\tSearch(ctx context.Context, collection string, params map[string]any) (any, error) \r\n\tCreate(ctx context.Context, collection string, document *bytes.Buffer, params map[string]any) (any, error) \r\n\tUpdate(ctx context.Context, collection string, document *bytes.Buffer, params map[string]any) (any, error) \r\n\tDelete(ctx context.Context, collection string, document *bytes.Buffer, params map[string]any) (any, error) \r\n\t \r\n\tRetrieve(ctx context.Context, collection string, params map[string]any) (any, error) \r\n\tListFields(ctx context.Context, collection string, params map[string]any) (any, error) \r\n\tAddField(ctx context.Context, collection string, document *bytes.Buffer) (any, error) \r\n\tUpdateField(ctx context.Context, collection string, document *bytes.Buffer) (any, error) \r\n\tDeleteField(ctx context.Context, collection string, document *bytes.Buffer) (any, error)\r\n\t```\r\n\r\n## 🛠 Enhancements\r\n- Added mocks for HTTP Service\r\nMocks to test GoFr HTTP client had to be generated manually. Now, mocks for the HTTP service has been added in GoFr's `MockContainer`.\r\n ### Usage:\r\n ```\r\n // register HTTP services to be mocked\r\n httpservices := []string{\"cat-facts\", \"cat-facts1\", \"cat-facts2\"} \r\n \r\n // pass the httpservices in NewMockContainer\r\n _, mock := NewMockContainer(t, WithMockHTTPService(httpservices...)) \r\n \r\n // Set mock expectations using the mocks from NewMockContainer\r\n mock.HTTPService.EXPECT().Get(context.Background(), \"fact\",map[string]interface{}{ \r\n \"max_length\": 20, \r\n }).Return(result, nil) \r\n \r\n // Call to your function where HTTPService has to be mocked\r\n .\r\n .\r\n .\r\n ```\r\n\r\n", + "date": "2024-09-16T11:34:16Z", + "tag": "v1.20.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.20.0" + }, + { + "body": "# Release v1.19.1\r\n\r\n## 🛠 Enhancements\r\n- Support for S3 operations\r\nFileStore can now be initialised as S3 with the `AddFileStore` method. \r\nSince, S3 is an external datasource, it can be imported by: \r\n`go get gofr.dev/pkg/gofr/datasource/file/s3`\r\n\r\n\t**Example:** \r\n`app.AddFileStore(s3.New(&s3.Config{EndPoint: \"http://localhost:4566\", BucketName: \"gofr-bucket-2\", Region: \"us-east-1\", AccessKeyID: \"test\", SecretAccessKey: \"test\"}))`\r\n\r\n\tSupported functionalities are:\r\n\t```\r\n\t Create(name string) (File, error)\r\n\t Mkdir(name string, perm os.FileMode) error\r\n\t MkdirAll(path string, perm os.FileMode) error\r\n\t Open(name string) (File, error)\r\n\t OpenFile(name string, flag int, perm os.FileMode) (File, error)\r\n\t Remove(name string) error\r\n\t RemoveAll(path string) error\r\n\t Rename(oldname, newname string) error\r\n\t ReadDir(dir string) ([]FileInfo, error)\r\n\t Stat(name string) (FileInfo, error)\r\n\t Getwd() (string, error)\r\n\t```\r\n\r\n## 🐞 Fixes\r\n- Resolved SQL mocks\r\nPreviously the mock was not able to mock Query, QueryRow, Select, Dialect, HealthCheck methods. Hence, replaced mock-gen generated SQL mocks with go-mock-sql package in the mock container.", + "date": "2024-09-09T12:20:50Z", + "tag": "v1.19.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.19.1" + }, + { + "body": "# Release v1.19.0\r\n\r\n## ✨ Features\r\n- Support for second in cron format\r\nCron job schedules can now be more precise with an optional addition field for seconds.\r\nFormat can now be either 5 part or 6 part, denoting `second (optional), minute, hour, day_of_month, month, day_of_week`.\r\n\r\n **Example:**\r\n ```\r\n // Cron job to run every 10 second\r\n app.AddCronJob(\"*/10 * * * * *\", \"counter\", count)\r\n // Cron job to run every 5 minute\r\n app.AddCronJob(\"*/5 * * * *\", \"counter\", count)\r\n ```\r\n\r\n- Support for SFTP operations\r\nFileStore can now be initialised as SFTP with the `AddFileStore` method.\r\nSince, SFTP is an external datasource, it can be imported by:\r\n`go get gofr.dev/pkg/gofr/datasource/file/sftp`\r\n\t\r\n\t**Example:**\r\n`app.AddFileStore(sftp.New(&sftp.Config{Host: \"127.0.0.1\",\r\nUser: \"user\",\r\nPassword: \"password\",\r\nPort: 22}))`\r\n\r\n\tSupported functionalities are:\r\n\t```\r\n\tCreate(name string) (File, error)\r\n\tMkdir(name string, perm os.FileMode) error\r\n\tMkdirAll(path string, perm os.FileMode) error\r\n\tOpen(name string) (File, error)\r\n\tOpenFile(name string, flag int, perm os.FileMode) (File, error)\r\n\tRemove(name string) error\r\n\tRemoveAll(path string) error\r\n\tRename(oldname, newname string) error\r\n\tReadDir(dir string) ([]FileInfo, error)\r\n\tStat(name string) (FileInfo, error)\r\n\tGetwd() (string, error)\r\n\t```\r\n \r\n \r\n## 🛠 Enhancements\r\n- Response with Partial Content status code\r\nIf the handler returns both data as well as error, then the status code would now be Partial Content `206`\r\n\r\n- Enhance Observability for FTP\r\nLogs formatting and structuring have been improved.\r\nA new histogram metric `app_ftp_stats` has been introduced to populate data for execution duration with labels as `type` and `status`.\r\n![Image](https://media.discordapp.net/attachments/1257270270583111700/1280116980438794315/Screenshot_2024-09-02_at_4.17.16_PM.png?ex=66d6e957&is=66d597d7&hm=ef375e196139b4c8459f4df8c64d02dc56747208ef3bc7a091155003da51413b&=&format=webp&quality=lossless&width=2160&height=196)\r\n\r\n- Logger mock methods for testing purpose\r\nTo help test the logging methods, mocks have now been generated with `mockgen`, instead of manually creating for every datasource.\r\n\r\n## 🐞 Fixes\r\n- Resolved permission issues in directories\r\nWhile creating new directory, the permissions were missing for the directory. Fixed that by providing `ModePerm` (`777`) permissions.", + "date": "2024-09-02T11:48:49Z", + "tag": "v1.19.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.19.0" + }, + { + "body": "# Release v1.18.0\r\n\r\n## ✨ Features\r\n- SQL Tags in AddRESTHandlers\r\nThe `AddRESTHandlers` function now supports the following SQL tags for enhanced data integrity and database handling:\r\n - `auto_increment`:\r\n When this tag is applied to a struct field, any provided ID value will be ignored. Instead, the ID returned by the database after insertion will be used.\r\n - `not_null`:\r\n This tag enforces a non-null constraint at the service level, ensuring that no nil value can be sent for the specified field.\r\n Incase nil value is sent, error will be returned.\r\n\r\n Example:\r\n ```go\r\n type user struct {\r\n\t ID \t\tint \t`json:\"id\" \tsql:\"auto_increment\"`\r\n\t Name \tstring \t`json:\"name\" \tsql:\"not_null\"`\r\n\t Age \tint \t`json:\"age\"`\r\n\t IsEmployed \tbool \t`json:\"isEmployed\"`\r\n }\r\n ```\r\n\r\n- Added support for directory operations in FileSystem\r\nSupported functionalities are:\r\n`ChDir(dirname string) error` - ChDir changes the current directory.\r\n`Getwd() (string, error)` - Getwd returns the path of the current directory.\r\n`ReadDir(dir string) ([]FileInfo, error)` - ReadDir returns a list of files/directories present in the directory.\r\n`Stat(name string) (FileInfo, error)` - Stat returns the file/directory information in the directory.\r\n\r\n## 🛠 Enhancements\r\n- Error logs for invalid configs\r\nAdded validations for `REQUEST_TIMEOUT` and `REMOTE_LOG_FETCH_INTERVAL` configs and log error if invalid.\r\n\r\n- Error logs for internal server errors\r\nPreviously, if any occurred then there was a log with just status code and correlationID.\r\nHence, added an error log with correlationID and `error message`.\r\n![image](https://github.com/user-attachments/assets/b1b4dcb5-f66e-4404-888b-ea6a369dee2d)\r\n\r\n- FileSystem mock methods for testing purpose\r\nTo help test the FileSystem methods, mocks have now been added to mock container struct which can be generated from `NewMockContainer` method.\r\n\r\n## 🐞 Fixes\r\n- Resolved application status in case of migration failure\r\nIf any occurs while running the migrations, the application will now gracefully `shutdown`.\r\n\r\n- Resolved response for error case\r\nFor an error case, where the response consists of error message only and has no data to return, then also the data field was present in output as `null`.\r\nThis has been removed now, so only error struct will be returned with respective status code.", + "date": "2024-08-26T07:49:39Z", + "tag": "v1.18.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.18.0" + }, + { + "body": "# Release v1.17.0\r\n\r\n## ✨ Features\r\n- Added support for FTP as an external datasource\r\nFTP can be added using the method on gofrApp `AddFTP(fs file.FileSystemProvider)`\r\nSupported functionalities are:\r\n`Create(name string) (File, error)`\r\n `Mkdir(name string, perm os.FileMode) error`\r\n `MkdirAll(path string, perm os.FileMode) error`\r\n`Open(name string) (File, error)`\r\n`OpenFile(name string, flag int, perm os.FileMode) (File, error)`\r\n`Remove(name string) error`\r\n`RemoveAll(path string) error`\r\n`Rename(oldName, newName string) error`\r\n\r\n- Cassandra now supports Batching\r\nAdded Batch functionality with newly introduced methods:\r\n`NewBatch(batchType int) error`\r\n`BatchQuery(stmt string, values ...interface{})`\r\n`ExecuteBatch() error`\r\n\r\n- Automated injection of `gofr.Context` in the gRPC server during registering of the gRPC service\r\ngRPC can now inject gofr `container` to the `Server` struct, to access logger, datasources, and other functionalities provided by gofr.\r\nRefer to [example](https://github.com/gofr-dev/gofr/blob/development/examples/grpc-server/grpc/server.go) for detailed info.\r\n\r\n## 🛠 Enhancements\r\n- Messages can now be written to WebSocket without returning\r\nAdded method on gofrContext `WriteMessageToSocket(data any) error` to write a message.\r\n\r\n## 🐞 Fixes\r\n- Resolved panic for EnableBasicAuth\r\nIf an odd no. of arguments (user, password) were passed to the `EnableBasicAuth` method, the app panicked. Fixed this issue, user and password can be passed in the method as comma-separated pairs like:\r\n`EnableBasicAuth(user1, pass1, user2, pass2)`\r\n\r\n- Resolved authentication for EnableBasicAuth\r\nEven if the credentials were correct, the app was returning the `401` status Unauthorised instead of the expected `200`.\r\n\r\n- Fixed unstructured log in Mongo\r\nDebug query logs were not properly formatted for Mongo, fixed the formatting.\r\nThe `message` field in logs was `string` type, updated it to `object`", + "date": "2024-08-12T09:23:23Z", + "tag": "v1.17.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.17.0" + }, + { + "body": "# Release v1.16.1\r\n\r\n## 🐞 Fixes\r\n- Resolved DB migrations panic in logging\r\nApp was panicking while logging with migrations datasource, as the logger was `nil`. Now, populated the logger, hence fixing the panic.\r\n- Removed unexpected error log for tracing when it was not enabled from configs\r\n`{\"level\":\"ERROR\",\"time\":\"2024-08-06T17:47:56.714963+05:30\",\"message\":\"unsupported TRACE_EXPORTER: \",\"gofrVersion\":\"v1.16.0\"}`\r\nThe above log was printed when tracing configs (TRACE_EXPORTER, TRACER_URL) weren't provided, and since tracing is optional feature, removed error log if configs aren't given.", + "date": "2024-08-06T15:17:24Z", + "tag": "v1.16.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.16.1" + }, + { + "body": "# Release v1.16.0\r\n\r\n## ✨ Features\r\n- Application will now gracefully shutdown to prevent data loss during application termination\r\nAll the processes (go-routines) will be awaited to finish before shutting down. Currently, the timeout for shutdown is `30 seconds`. Will be making it configurable in upcoming release.\r\n\r\n- Enhanced query parameter handling to support multiple values\r\nPreviously, only a single value was supported for query params with `Param(key string) string` method. Now, added another method `Params(key string) []string` which returns array of values passed for given query param.\r\nExample:\r\n ```\r\n If URL is \r\n - http://order-service/orders?id=123,234\r\n - http://order-service/orders?id=123&id=234\r\n \r\n Then ctx.Params(\"id\") will return [\"123\", \"234\"]\r\n ```\r\n\r\n- Enhanced security with SSL support for PostgreSQL connections\r\nDefault certificates can now be used as SSL, by configuring `DB_SSL_MODE` as `require`.\r\nCurrently this is only supported with PostgreSQL. Custom certificates and other DBs will be supported in future releases.\r\n\r\n## 🛠 Enhancements\r\n- Improved logging for tracer configs validation\r\nTracing is only enabled when `both` TRACE_EXPORTER and TRACER_URL are provided, so added error logs if any one of them is provided and the other is missing.\r\n\r\n \"Screenshot\r\n\r\n \"Screenshot\r\n\r\n- Improved tracing with OpenTelemetry protocol integration\r\nTracing can now be configured as otel protocol by configuring `TRACE_EXPORTER` as `otlp`, and providing `TRACER_URL`.\r\n\r\n## 🐞 Fixes\r\n- Resolved panic caused by passing non-pointer objects in AddRESTHandlers method\r\nApp was panicking while initialising if the argument is passed by value to `AddRESTHandlers` method. Since, the method only accepts arguments passed by reference, added validations and error log instead of panic.", + "date": "2024-08-05T07:01:14Z", + "tag": "v1.16.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.16.0" + }, + { + "body": "# Release v1.15.0\r\n\r\n## ✨ Features\r\n- Add support for BadgerDB as key value store. (#835) \r\n\r\n## 🛠 Enhancements\r\n- Fail app start in case of error in config file. (#854)\r\n- Add validations for tracer configs and log errors. (#859)\r\n\r\n#### Changelog: https://github.com/gofr-dev/gofr/compare/v1.14.1...v1.15.0", + "date": "2024-07-22T09:09:18Z", + "tag": "v1.15.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.15.0" + }, + { + "body": "# Release v1.14.1\r\n\r\n## 🐞 Fixes\r\n- Fix fatal log methods (#842)\r\n\r\n#### Changelog: https://github.com/gofr-dev/gofr/compare/v1.14.0...v1.14.1", + "date": "2024-07-12T12:21:25Z", + "tag": "v1.14.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.14.1" + }, + { + "body": "## This version contains breaking changes, please use [v1.14.1](https://github.com/gofr-dev/gofr/releases/tag/v1.14.1)\r\n\r\n# Release v1.14.0\r\n\r\n## ✨ Features\r\n- Add support for auth header for tracer exporter (#828)\r\nAuthorization header can be passed for tracer using `TRACER_AUTH_KEY` config\r\n\r\n- Add support for custom tracer URL (#834)\r\nTraces can now be posted to custom URL provided in `TRACER_URL` config\r\n\r\n**NOTE**: `TRACER_HOST` and `TRACER_PORT` are now deprecated, use `TRACER_URL` instead.\r\n\r\n#### Changelog: https://github.com/gofr-dev/gofr/compare/v1.13.0...v1.14.0", + "date": "2024-07-12T10:47:52Z", + "tag": "v1.14.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.14.0" + }, + { + "body": "## ✨ Features\r\n- Add support for profilling endpoints. (#774)\r\n- Add support for MQTT_KEEP_ALIVE. (#771)\r\n- Support transactions in MongoDB driver. (#779) \r\n- Add support for retry of failing downstream calls. (#778) \r\n\r\n## 🐞 Fixes\r\n- Fix MQTT messages being lost due to connection loss. (#771)\r\n- Fix request timeout for health check calls. (#777)\r\n- Fix dependent integration test in pub-sub example. (#784)\r\n- Fix MQTT tests using mock Client and mock Token. (#791)\r\n\r\n**Changelog**: https://github.com/gofr-dev/gofr/compare/v1.12.0...v1.13.0", + "date": "2024-07-08T10:18:53Z", + "tag": "v1.13.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.13.0" + }, + { + "body": "# Release v1.12.0\r\n\r\n## ✨ Features\r\n- Add support of migrations for ClickHouse DB. (#750)\r\n- Add support for serving static files. (#674)\r\n- Add support of mocks for external datasources. (#749)\r\n\r\n## 🛠 Enhancements\r\n- Update GO version to `v1.22` (#741)\r\n**NOTE**: Starting this version, supported GO versions are >= `v1.21`\r\n\r\n## 🐞 Fixes\r\n- Fix response of remote logging service. (#770)\r\n- Fix nil metrics issue for error cases. (#761)\r\n- Fix go.mod for examples. (#767)\r\n\r\n#### Changelog: https://github.com/gofr-dev/gofr/compare/v1.11.0...v1.12.0", + "date": "2024-06-28T11:53:32Z", + "tag": "v1.12.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.12.0" + }, + { + "body": "# Release v1.11.0\r\n\r\n## ✨ Features\r\n- Support for container in Auth Middlewares. (#738)\r\n\r\n## 🐞 Fixes\r\n- Fix `app_http_service_response` metric population for error case. (#743)\r\n- Add configs for idle and max open connections. (#739)\r\n- Add logging methods in migrations logger. (#727)\r\n\r\n#### Changelog: https://github.com/gofr-dev/gofr/compare/v1.10.0...v1.11.0", + "date": "2024-06-21T11:11:06Z", + "tag": "v1.11.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.11.0" + }, + { + "body": "# Release v1.10.0\r\n\r\n## ✨ Features\r\n- Support for WebSocket connections. (#692)\r\n- Add support to read form-data of type TEXT. (#718)\r\n- Add support for `StatusAccepted` response for POST endpoints. (#730)\r\n- Add support for ClickhouseDB. (#736)\r\n\r\n## 🐞 Fixes\r\n- Fix CMD responses followed by `%`. (#697)\r\n- Add missing health details in app health-check. (#706)\r\n- Fix request timeout response in text to JSON. (#716)\r\n- Fix the help option in CMD sub-commands. (#715)\r\n- Fix panic recovery for HTTP request. (#720)\r\n- Make Span logs descriptive by adding error origin. (#710)\r\n- Add mock metrics being used by framework by default in MockSQL. (#707)\r\n\r\n#### Changelog: https://github.com/gofr-dev/gofr/compare/v1.9.0...v1.10.0", + "date": "2024-06-18T11:12:50Z", + "tag": "v1.10.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.10.0" + }, + { + "body": "# Release v1.9.0\r\n## ✨ Features\r\n- Support for CASSANDRA as an external DB. (#654)\r\n- Support for local filestore. (#695)\r\n- Default Support for `--help` and `-h` for CMD applications to show help command. (#661)\r\n\r\n## 🐞 Fixes\r\n- Improve logging for SQL DB. (#655)\r\n- Fix Request timeout logs. (#699)\r\n\r\n#### Changelog: https://github.com/gofr-dev/gofr/compare/v1.8.1...v1.9.0", + "date": "2024-06-11T05:14:59Z", + "tag": "v1.9.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.9.0" + }, + { + "body": "# Release v1.8.1\r\n\r\n## 🐞 Fixes\r\n- Added missing QueryContext method in sql (https://github.com/gofr-dev/gofr/pull/671)\r\n- Bind consumes pub sub messages into `int`, `bool`, `string` and `float64`. (https://github.com/gofr-dev/gofr/pull/670)\r\n- Added entity already exists error (https://github.com/gofr-dev/gofr/pull/676)\r\n- Allow to change CORS headers using configs (https://github.com/gofr-dev/gofr/pull/669)\r\n- Fixed response and tracing in trace handler for [http-server](https://github.com/gofr-dev/gofr/blob/main/examples/http-server/main.go) example (https://github.com/gofr-dev/gofr/pull/684) (https://github.com/gofr-dev/gofr/pull/687)\r\n- Fixed misaligned terminal logs (https://github.com/gofr-dev/gofr/pull/688)\r\n\r\n\r\n**Full Changelog**: https://github.com/gofr-dev/gofr/compare/v1.8.0...v1.8.1", + "date": "2024-06-05T11:44:31Z", + "tag": "v1.8.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.8.1" + }, + { + "body": "# Release v1.8.0\r\n\r\n## ✨ Features\r\n- Added support to set table name and rest path in REST handlers. (#648)\r\n\r\n## 🐞 Fixes\r\n- Fixed OAuth call before refresh interval in case of error. (#665)\r\n\r\n#### Change log : https://github.com/gofr-dev/gofr/compare/v1.7.0...v1.8.0", + "date": "2024-05-28T12:41:11Z", + "tag": "v1.8.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.8.0" + }, + { + "body": "# Release v1.7.0\r\n\r\n## ✨ Features\r\n- Added observability support for MongoDB. (#616)\r\n- Enhanced metrics for datasources. (#630)\r\n- Added support for custom headers for HTTP client. (#611)\r\n- Added support for `REQUEST_TIMEOUT` for HTTP, with default value of 5 sec. (#628)\r\n- Added Kafka producer batch configurations. (#631)\r\n- Added support for SQLite datasource. (#646)\r\n- Added pre-defined errors, and support for custom errors. (#604)\r\n- Introduced Mongo package as a sub package in datasources. (#627)\r\n\r\n## 🐞 Fixes\r\n- Fixed formatting for service call logs. (#615)\r\n- Fixed formatting for Kafka logs. (#618)\r\n- Fixed log level for internal server error logs. (#625)\r\n- Improved datasource logs and added debug logs. (#632)\r\n\r\n**NOTE: UseMongo() is deprecated in this version, and will be removed in the upcoming versions. Please use AddMongo() instead.**\r\n\r\n#### Change log : https://github.com/gofr-dev/gofr/compare/v1.6.1...v1.7.0", + "date": "2024-05-27T06:37:46Z", + "tag": "v1.7.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.7.0" + }, + { + "body": "# Release v1.6.1\r\n\r\n## 🐞 Fixes\r\n- Added missing `PATCH` route registration. (#598)(#602)\r\n- Fixed `X-API-KEY` based auth for http service. (#612)\r\n\r\n#### Change log : https://github.com/gofr-dev/gofr/compare/v1.6.0...v1.6.1", + "date": "2024-05-14T09:32:42Z", + "tag": "v1.6.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.6.1" + }, + { + "body": "# Release v1.6.0\r\n\r\n## ✨ Features\r\n- Added support for SQL Keywords for CRUDHandlers. (#566)\r\n- Added support for custom favicon.ico. (#571)\r\n- Added support for cron job scheduling. (#592)\r\n- Added support for swagger endpoints. (#594)\r\n\r\n## 🐞 Fixes\r\n- Updated `CONSUMER_ID` to optional when publishing. (#581)\r\n- Moved MockLogger from `testutil` to `logging` package. (#582)\r\n- Fixed access to DB in Kafka consumers. (#585)\r\n\r\n#### Change log : https://github.com/gofr-dev/gofr/compare/v1.5.0...v1.6.0", + "date": "2024-05-12T09:00:55Z", + "tag": "v1.6.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.6.0" + }, + { + "body": "# Release v1.5.0\r\n\r\n## ✨ Features\r\n- Added support of postgreSQL for AddRESTHandlers. (#549)\r\n- Added support for custom middlewares. (#554)\r\n\r\n## 🐞 Fixes\r\n- Fixed logs structuring for PubSub. (#539)\r\n\r\n\r\n#### Change log : https://github.com/gofr-dev/gofr/compare/v1.4.0...v1.5.0", + "date": "2024-05-03T04:02:42Z", + "tag": "v1.5.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.5.0" + }, + { + "body": "# Release v1.4.1\r\n\r\n## 🐞 Fixes\r\n- Add retry for SQL connection (#530)\r\n- Add panic recovery for subscription and migrations to prevent server from crashing (#525)\r\n- Fix issue in `gofr_migrations` table creation (#531)", + "date": "2024-04-27T13:20:48Z", + "tag": "v1.4.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.4.1" + }, + { + "body": "# Release v1.4.0\r\n\r\n## ✨ Features\r\n- Add tracing support for SQL datasource.(#462)\r\n- Remove auth for routes with prefix `/.well-known` routes.(#476)\r\n- Add support for GoFr tracer to export traces on [tracer.gofr.dev](https://tracer.gofr.dev/) (#481)\r\n- Add support for labels in gauge metrics.(#490)\r\n- Add app_info metric to push `app_name`, `app_version` and `framework_version`.(#513)\r\n\r\n## 🐞 Fixes\r\n- Change keyword basic to Basic while checking Auth header in basic Auth. (#464)\r\n- Fix buckets for redis & sql metrics to microseconds from milliseconds. (#485)\r\n- Fix env override to support `.env` should overload `.local.env` or other env files. (#491)\r\n", + "date": "2024-04-20T13:14:11Z", + "tag": "v1.4.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.4.0" + }, + { + "body": "# Release v1.3.1\r\n\r\n## 🐞 Fixes\r\n\r\n- Fixed DockerFiles for examples (#453)\r\n- Fixed success status code for POST and DELETE (#452)\r\n- Fixed file name in documentation (#455)\r\n- Added jaeger as a valid trace exporter (#454)", + "date": "2024-04-10T12:33:24Z", + "tag": "v1.3.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.3.1" + }, + { + "body": "# Release v1.3.0\r\n\r\n## ✨ Features\r\n\r\n- Support for APP_ENV environment variable for reading different config files based on provided value of the variable. (#403)\r\n- Add support for using external mongo DB. (#435)\r\n- Fix mismatch in ports and health check URL in documentation. (#438)\r\n- Support for adding default REST endpoints using `AddRESTEndpoints`. (#406)\r\n\r\n## 🐞 Fixes\r\n\r\n- Convert the concrete struct types to interfaces for SQL and Redis datasources in container. (#426) \r\n- Fix wait-groups in case of server-start error. (#436)\r\n- Change the time-stamp value from microseconds to milliseconds for all logs. (#410)", + "date": "2024-04-06T10:43:16Z", + "tag": "v1.3.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.3.0" + }, + { + "body": "# Release v1.2.1\r\n\r\n## 🐞 Fixes\r\n- Added Access-Control-Allow-Headers to fix CORS issue.\r\n- Standardize log formatting and sanitize SQL and Redis queries before logging.", + "date": "2024-03-27T15:58:31Z", + "tag": "v1.2.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.2.1" + }, + { + "body": "# Release v1.2.0\r\n\r\n## ✨ Features\r\n- Add support for binding files along with `zip` file support and `multipart.FileHeader`.\r\n- Add support for user-defined HTTP Client Options.\r\n- Add support for registering routes on PATCH method.\r\n\r\n## 🐞 Fixes\r\n- Fix missing logs for MQTT, Google PubSub and Migrations.", + "date": "2024-03-22T15:05:05Z", + "tag": "v1.2.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.2.0" + }, + { + "body": "# Release v1.1.1\r\n\r\n## 🐞 Fixes\r\n- Add missing gofr framework version to metrics, logs, and traces", + "date": "2024-03-14T12:45:14Z", + "tag": "v1.1.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.1.1" + }, + { + "body": "# Release v1.0.0\r\n\r\n## ✨ Features\r\n- Add Support for [Basic, Api-Key and OAuth](https://gofr.dev/docs/advanced-guide/http-authentication) authentication mechanisms.\r\n- Add support for [MQTT](https://gofr.dev/docs/advanced-guide/using-publisher-subscriber#mqtt) publish-subscribe model.\r\n\r\n**Full Changelog**: https://github.com/gofr-dev/gofr/compare/v1.0.2...v1.1.0", + "date": "2024-03-12T03:56:47Z", + "tag": "v1.1.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.1.0" + }, + { + "body": "# Release v1.0.3\r\n\r\n## 🐞 Fixes\r\n- Fix grpc support link in readme and add the same to [gofr.dev](https://gofr.dev/docs/advanced-guide/grpc).\r\n- Add missing health check for PubSub (Google PubSub and Kafka).\r\n- Add missing migrations for PubSub (Create and Delete topics).\r\n- Fix migration panic when SQL is not initialized.", + "date": "2024-03-06T13:53:01Z", + "tag": "v1.0.3", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.0.3" + }, + { + "body": "# Release v1.0.2\r\n\r\n## 🐞 Fixes\r\n- Fix duration for SQL query log and metrics.\r\n- Update metrics value format and histogram buckets of time duration from `seconds` to `microseconds` for following datasources:\r\n\t- **Redis**:\r\n\t\t- Previous: `{.001, .003, .005, .01, .02, .03, .05, .1, .2, .3, .5, .75, 1, 2, 3, 5, 10, 30}`\r\n\t\t- Now: `{50, 75, 100, 125, 150, 200, 300, 500, 750, 1000, 1250, 1500, 2000, 2500, 3000}`\r\n\t- **SQL**:\r\n\t\t- Previous: `{.001, .003, .005, .01, .02, .03, .05, .1, .2, .3, .5, .75, 1, 2, 3, 5, 10, 30}`\r\n\t\t- Now: `{50, 75, 100, 125, 150, 200, 300, 500, 750, 1000, 2000, 3000, 4000, 5000, 7500, 10000}`\r\n- Add missing metrics for PubSub :\r\n\t- app_pubsub_publish_total_count: Number of total publish operations.\r\n\t- app_pubsub_publish_success_count: Number of successful publish operations.\r\n\t- app_pubsub_subscribe_total_count: Number of total subscribe operations.\r\n\t- app_pubsub_subscribe_success_count: Number of successful subscribe operations.\r\n", + "date": "2024-03-04T12:56:04Z", + "tag": "v1.0.2", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.0.2" + }, + { + "body": "# Release v1.0.1\r\n\r\n## 🐞 Fixes\r\n- Fixed content-type header for HTTP responses\r\n- Removed non-necessary logs from CMD application start", + "date": "2024-03-01T11:22:05Z", + "tag": "v1.0.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.0.1" + }, + { + "body": "# Release v1.0.0\r\n\r\n## ✨ Features\r\n- Publisher-Subscriber support for Apache Kafka and Google PubSub.\r\n- Postgres support for the SQL database has been added, `DB_DIALECT` is the environment variable used to define which driver is used by GoFr application.\r\n- Added `REMOTE_LOG_FETCH_INTERVAL` to let the user configure log fetch interval from the remote logging service (default value is 15 seconds).\r\n- Add `ExecContext` method for SQL datasources.\r\n\r\n## 🐞 Fixes\r\n- Renamed the `DB` object to `SQL` in container and migration datasources.\r\n- Fix response message of aliveness handler to the following : \r\n`{\r\n \"data\": {\r\n \"status\": \"UP\"\r\n }\r\n}`\r\n- Fix JSON keys for redis migration entry to follow camelcase.", + "date": "2024-02-27T11:38:15Z", + "tag": "v1.0.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v1.0.0" + }, + { + "body": "# Release v0.3.0\r\n\r\n## ✨ Features\r\n- Migrations Support for MySQL and REDIS.\r\n\t\t\r\n- Metrics - The following metrics are now being pushed by default.\r\n**System Info**\r\n\t\t- app_go_routines : Number of Go routines running.\r\n\t\t- app_sys_memory_alloc : Number of bytes allocated for heap objects.\r\n\t\t- app_sys_total_alloc : Number of cumulative bytes allocated for heap objects.\r\n\t\t- app_go_numGC : Number of completed Garbage Collector cycles.\r\n\t\t- app_go_sys : Number of total bytes of memory.\r\n\r\n\t **HTTP**\r\n\t\t- app_http_response : Response time of HTTP requests in seconds.\r\n\t\t- app_http_service_response : Response time of HTTP service requests in seconds.\r\n\r\n\t **Redis**\r\n\t\t- app_redis_stats : Observes the response time for Redis commands. \r\n\t\t \r\n\t **SQL**\r\n\t\t- app_sql_stats : Histogram metric response time of HTTP requests in seconds.\r\n\t\t- app_sql_open_connections : Number of open SQL connections.\r\n\t\t- app_sql_inUse_connections : Number of inUse SQL connections.\r\n\r\n## 🐞 Fixes\r\n- Add PUT Method in circuit breaker.\r\n- Add check to handle panic when the command line application's last argument is `-`.", + "date": "2024-02-19T12:37:37Z", + "tag": "v0.3.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v0.3.0" + }, + { + "body": "# Release v0.2.0\r\n\r\n## ✨ Features\r\n- HTTP Client for performing HTTP calls with the following options - \r\n (These options are order-agnostic and will override specific functionalities over basic HTTP calls)\r\n - Circuit Breaker for automatically cutting off service calls if the downstream service constantly throws 5xx.\r\n - Health Configs for allowing custom health-check endpoints to be configured to perform health checks.\r\n \r\n- Introduced `/.well-known/alive` default endpoint to check if the application is serving incoming requests.\r\n\r\n- Introduced formatted logging for SQL queries, Redis queries, and HTTP service calls, where data is formatted to look readable and properly formatted to make it easy for users to debug and find important logs.\r\n\r\n- Remote Log Level Change - users can provide a service URL that provides data to change the log level for the application without stopping and re-running the application.\r\n\r\n- Metrics - creating metrics and updating their values by open telemetry standards with support for the following metrics using Prometheus as an exporter and exposing these on a customizable port and `/metrics` endpoint : \r\n - **Counter**: A metric whose values are strictly increasing.\r\n - **UpDownCounter**: A metric that increases or decreases from the current value by a certain value.\r\n - **Histogram**: A metric that samples observations (like request durations or response sizes) and counts them in configurable buckets. It also provides a sum of all observed values.\r\n - **Gauge**: A metric representing a single numerical value that can arbitrarily go up and down, this change is not dependent on the previous value of the metric.\r\n\r\n## 🐞 Fixes\r\n- Tracing has been fixed where the traces were not in order and appeared to be in a non-hierarchal manner\r\n- Refactored the implementation and response for `/.well-known/health`", + "date": "2024-02-09T15:36:19Z", + "tag": "v0.2.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v0.2.0" + }, + { + "body": "\r\n## What's Changed\r\n\r\n### 🔧 Features\r\n* Add querry logger for redis by @Umang01-hash in https://github.com/gofr-dev/gofr/pull/209\r\n* Add HTTP Call methods in `new.go` for interservice calls with Logs by @aryanmehrotra in https://github.com/gofr-dev/gofr/pull/210\r\n* Add Redis Healthcheck & Refactor Health check by @aryanmehrotra in https://github.com/gofr-dev/gofr/pull/216\r\n\r\n\r\n### 🔧 Enhancements\r\n* Add CMD unit tests by @aryanmehrotra in https://github.com/gofr-dev/gofr/pull/205\r\n* Add tests for Logger , Service pkg by @Umang01-hash in https://github.com/gofr-dev/gofr/pull/195\r\n* Increase coverage for examples, cmd, config, grpc, http by @srijan-27 in https://github.com/gofr-dev/gofr/pull/201\r\n* Add Tests for Container, Context, CMD and Database by @aryanmehrotra in https://github.com/gofr-dev/gofr/pull/189\r\n* Update branch with main in workflow by @srijan-27 in https://github.com/gofr-dev/gofr/pull/181\r\n* Add tests for db, gofr, grpc, handler and httpServer by @vipul-rawat in https://github.com/gofr-dev/gofr/pull/197\r\n* Add security, licence, code of conduct and contribution guidelines by @aryanmehrotra in https://github.com/gofr-dev/gofr/pull/188\r\n* Refactor tests for logger package by @Umang01-hash in https://github.com/gofr-dev/gofr/pull/204\r\n* Removing deprecated linter from config by @vikash\r\n* Using 256 bit color for terminal log display by @vikash\r\n* Pretty printing SQL Logs by @vikash\r\n* Restructuring SQL to add health-check structure by @vikash\r\n* Add Quick Start Docs by @Umang01-hash in https://github.com/gofr-dev/gofr/pull/220\r\n\r\n### 📦 Dependency updates\r\n* Upgrading redis library by @vikash in https://github.com/gofr-dev/gofr/pull/196\r\n* Bump github.com/DATA-DOG/go-sqlmock from 1.5.1 to 1.5.2 by @dependabot in https://github.com/gofr-dev/gofr/pull/215\r\n* Upgrade dependencies by @vipul-rawat in https://github.com/gofr-dev/gofr/pull/185\r\n* Bump golang.org/x/term from 0.0.0-20201126162022-7de9c90e9dd1 to 0.15.0 by @dependabot in https://github.com/gofr-dev/gofr/pull/178\r\n\r\n## New Contributors\r\n* @srijan-27 made their first contribution in https://github.com/gofr-dev/gofr/pull/181\r\n\r\n**Full Changelog**: https://github.com/gofr-dev/gofr/compare/v0.0.1...v0.1.0", + "date": "2024-01-22T12:57:55Z", + "tag": "v0.1.0", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v0.1.0" + }, + { + "body": "# v0.0.1\r\n\r\nDear GoFr Community,\r\n\r\nWe're thrilled to announce that GoFr is now an open-source project, marking a new chapter in its evolution. We extend our heartfelt gratitude to all past and present contributors who've been instrumental in GoFr's development.\r\n\r\nAs part of our security measures, we've removed the complete project history, ensuring its integrity moving forward.\r\n \r\nBy making GoFr open source, we aim to foster a collaborative environment for developers of all backgrounds to innovate and enhance the project.\r\n\r\nWe invite you to explore the newly open-sourced GoFr, fork it, and contribute to its development. Your expertise is invaluable, and we look forward to new ideas and collaborative efforts.\r\n\r\nFeel free to reach out with questions, feedback, or suggestions. Thank you for your contributions and support. \r\n\r\nLet's shape GoFr's next chapter together!\r\n\r\n## Release Notes\r\n### Features\r\n\r\n- REST, gRPC server and CMD creation\r\n- Support for SQL and NoSQL Data Stores with Auto-Initialization\r\n - **SQL**: MySQL\r\n - **Cache** : Redis\r\n- Predefined logs with log levels for STDOUT and JSON", + "date": "2024-01-04T12:15:57Z", + "tag": "v0.0.1", + "url": "https://github.com/gofr-dev/gofr/releases/tag/v0.0.1" + } +] diff --git a/src/app/cli/gofr/page.jsx b/src/app/cli/gofr/page.jsx index 8fdde1b..bd071a9 100644 --- a/src/app/cli/gofr/page.jsx +++ b/src/app/cli/gofr/page.jsx @@ -1,17 +1,65 @@ -import React from 'react'; +import React from 'react' +import Link from 'next/link' +export const metadata = { + title: 'GoFr CLI — Project Scaffolding for the Go Framework', + description: + 'GoFr CLI is the command-line tool for initializing GoFr projects, generating boilerplate, and running framework-aware tasks for Go microservices.', + alternates: { + canonical: '/cli/gofr', + }, +} const Page = () => { - return ( -
    -
    - - Documentation - - Coming Soon -
    -
    - ); -}; + return ( +
    +

    + GoFr CLI +

    +

    + The command-line tool for initializing projects and performing tasks with the GoFr framework. +

    -export default Page; \ No newline at end of file +
    +

    Installation

    + + go install gofr.dev/cli/gofr@latest + +
    + +
    + +
    +
    +

    + CLI Documentation +

    +

    + Full reference for all CLI commands and options. +

    +
    + + +
    +
    +

    + GitHub Repository +

    +

    + Source code, issues, and contributions. +

    +
    + +
    +
    + ) +} + +export default Page diff --git a/src/app/comparison/layout.jsx b/src/app/comparison/layout.jsx new file mode 100644 index 0000000..b9d1c77 --- /dev/null +++ b/src/app/comparison/layout.jsx @@ -0,0 +1,4 @@ +import { MarketingPage } from '@/components/MarketingPage' + +const Layout = ({ children }) => {children} +export default Layout diff --git a/src/app/docs/layout.jsx b/src/app/docs/layout.jsx index a0cc982..9913d20 100644 --- a/src/app/docs/layout.jsx +++ b/src/app/docs/layout.jsx @@ -1,4 +1,3 @@ -'use client' import { DocsPage } from '@/components/DocsPage' const Layout = ({ children }) => { diff --git a/src/app/events/events.json b/src/app/events/events.json index 53c1846..76572c0 100644 --- a/src/app/events/events.json +++ b/src/app/events/events.json @@ -1,38 +1,26 @@ [ { - "date": "10-02-2020", - "title": "GopherCon Africa", - "description": "GoFr received an amazing response at GopherCon Africa! We showcased our seamless database integration, HTTP/gRPC support, observability, and WebSockets.", - "imageSrc": "https://media.discordapp.net/attachments/1230609009162059836/1301136150156677141/1729836948894.jpeg?ex=67620038&is=6760aeb8&hm=4cbee5de4bec5f526b941db402a3d1607c990054c3cf1853edb4934c70f776ba&=&format=webp&width=2160&height=944" - }, - { - "date": "2021", - "title": "Open Source India 2024", - "description": "At Open Source India in Bengaluru, we kicked off with an amazing response at our booth on 23rd and an interactive Developer’s Meet on Oct 24th. It was a pleasure connecting with everyone at our booth, where demos highlighted GoFr’s innovative approach to writing microservices, making backend development simpler and more efficient.", - "imageSrc": "https://media.discordapp.net/attachments/1230609009162059836/1301136149749698650/1729836948365.jpeg?ex=67620038&is=6760aeb8&hm=f43bbf9dacbc631f36dfa7ae4402f61caaddcde1c8e4357236418d11c86d8006&=&format=webp&width=1418&height=1056" + "date": "23-24th November, 2024", + "title": "GoFr Hackathon", + "description": "GoFr Hackathon was a major success with participants building innovative solutions using the GoFr framework. It was an exciting two-day event where developers and tech enthusiasts came together to collaborate and create.", + "imageSrc": "/events/hackathon.jpg" }, { - "date": "2022", - "title": "GoFr is on a roll with its workshops!", - "description": "Past two months, we’ve hosted workshops at top colleges such as IIT BHU, IIIT Sri City, Thapar University, JIIT Noida, NIT Jalandhar, and NIT Nagpur. At Gravitas in VIT Vellore, we proudly supported the Hack the Hackathon event, where students explored GoFr and contributed innovative ideas to enhance the framework.", - "imageSrc": "https://media.discordapp.net/attachments/1230609050899710052/1301491118780973137/WhatsApp_Image_2024-10-30_at_15.47.27.jpeg?ex=6761f94f&is=6760a7cf&hm=4bc52e39b921aeb00e444522fa49744dcbfa9d6fb7e35b1d3b2c167b6b6111d9&=&format=webp&width=1408&height=1056" + "date": "23-24th October, 2024", + "title": "Open Source India", + "description": "At Open Source India, we had an amazing experience connecting with the open-source community. The event featured various sessions, demos, and showcases on GoFr, highlighting its role in simplifying backend development and its microservice approach.", + "imageSrc": "/events/OpenSourceIndia.jpeg" }, { - "date": "2020", + "date": "18-19th October, 2024", "title": "GopherCon Africa", - "description": "GoFr received an amazing response at GopherCon Africa! We showcased our seamless database integration, HTTP/gRPC support, observability, and WebSockets.", - "imageSrc": "https://media.discordapp.net/attachments/1230609009162059836/1301136150156677141/1729836948894.jpeg?ex=67620038&is=6760aeb8&hm=4cbee5de4bec5f526b941db402a3d1607c990054c3cf1853edb4934c70f776ba&=&format=webp&width=2160&height=944" - }, - { - "date": "2021", - "title": "Open Source India 2024", - "description": "At Open Source India in Bengaluru, we kicked off with an amazing response at our booth on 23rd and an interactive Developer’s Meet on Oct 24th. It was a pleasure connecting with everyone at our booth, where demos highlighted GoFr’s innovative approach to writing microservices, making backend development simpler and more efficient.", - "imageSrc": "https://media.discordapp.net/attachments/1230609009162059836/1301136149749698650/1729836948365.jpeg?ex=67620038&is=6760aeb8&hm=f43bbf9dacbc631f36dfa7ae4402f61caaddcde1c8e4357236418d11c86d8006&=&format=webp&width=1418&height=1056" + "description": "At GopherCon Africa, GoFr stood out with its cutting-edge tools and integration features, making backend development easier. We showcased GoFr's capabilities in working with databases, observability tools, and its seamless HTTP/gRPC support.", + "imageSrc": "/events/gopherconAfrica.jpeg" }, { - "date": "2022", - "title": "GoFr is on a roll with its workshops!", - "description": "Past two months, we’ve hosted workshops at top colleges such as IIT BHU, IIIT Sri City, Thapar University, JIIT Noida, NIT Jalandhar, and NIT Nagpur. At Gravitas in VIT Vellore, we proudly supported the Hack the Hackathon event, where students explored GoFr and contributed innovative ideas to enhance the framework.", - "imageSrc": "https://media.discordapp.net/attachments/1230609050899710052/1301491118780973137/WhatsApp_Image_2024-10-30_at_15.47.27.jpeg?ex=6761f94f&is=6760a7cf&hm=4bc52e39b921aeb00e444522fa49744dcbfa9d6fb7e35b1d3b2c167b6b6111d9&=&format=webp&width=1408&height=1056" + "date": "September 2024", + "title": "GoFr Workshops", + "description": "GoFr workshops are held regularly to engage with developers and tech enthusiasts. We’ve conducted workshops across multiple cities such as IIT BHU, IIIT Sri City, Thapar University, JIIT Noida, NIT Jalandhar, and NIT Nagpur offering hands-on experiences and deep dives into GoFr’s powerful features.", + "imageSrc": "/events/WorkShop.jpeg" } ] diff --git a/src/app/events/layout.jsx b/src/app/events/layout.jsx new file mode 100644 index 0000000..cd3a11c --- /dev/null +++ b/src/app/events/layout.jsx @@ -0,0 +1,27 @@ +import React from 'react' + +export const metadata = { + title: 'GoFr Events — Conferences, Meetups & Talks', + description: + 'Upcoming and past GoFr events: conference talks, meetups, workshops, and community gatherings about the opinionated Go microservice framework.', + metadataBase: new URL('https://gofr.dev'), + alternates: { canonical: '/events' }, + openGraph: { + type: 'website', + url: 'https://gofr.dev/events', + title: 'GoFr Events', + description: + 'Upcoming and past GoFr events: talks, meetups, workshops, and community gatherings.', + images: [{ url: '/opengraph-image.png', width: 1200, height: 630 }], + }, + twitter: { + card: 'summary_large_image', + site: '@gofr_dev', + title: 'GoFr Events', + description: 'Talks, meetups, workshops, and community gatherings.', + images: ['/twitter-image.png'], + }, +} + +const Layout = ({ children }) => children +export default Layout diff --git a/src/app/examples/examples.json b/src/app/examples/examples.json new file mode 100644 index 0000000..bdc4972 --- /dev/null +++ b/src/app/examples/examples.json @@ -0,0 +1,19 @@ +[ + { "title": "HTTP Server", "description": "Basic REST API server with CRUD endpoints, Redis caching, and structured responses.", "tags": ["REST", "Getting Started"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/http-server", "featured": true }, + { "title": "gRPC Server", "description": "Build a gRPC service with protocol buffers, streaming, and automatic observability.", "tags": ["gRPC", "Communication"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/grpc", "featured": true }, + { "title": "Publisher", "description": "Publish messages to Kafka, Google Pub/Sub, NATS, or MQTT with a unified API.", "tags": ["Pub/Sub", "Messaging"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-publisher", "featured": true }, + { "title": "Subscriber", "description": "Subscribe to message topics with automatic offset management and error handling.", "tags": ["Pub/Sub", "Messaging"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-subscriber" }, + { "title": "HTTP Server with Redis", "description": "REST API backed by Redis for caching and session management.", "tags": ["REST", "Redis", "Database"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/http-server-using-redis" }, + { "title": "REST Handlers", "description": "Auto-generate CRUD endpoints by implementing the REST interface.", "tags": ["REST", "Getting Started"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-add-rest-handlers" }, + { "title": "Data Migrations", "description": "Run versioned schema migrations across MySQL, PostgreSQL, Redis, and MongoDB.", "tags": ["Database", "Migrations"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-migrations" }, + { "title": "GraphQL API", "description": "Schema-first GraphQL with resolvers, playground, and built-in observability.", "tags": ["GraphQL", "Communication"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-graphql" }, + { "title": "WebSocket", "description": "Real-time bidirectional communication with WebSocket support.", "tags": ["WebSocket", "Communication"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-web-socket" }, + { "title": "Cron Jobs", "description": "Schedule recurring tasks with cron expressions and automatic metrics.", "tags": ["Background", "Scheduling"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-cron-jobs" }, + { "title": "Custom Metrics", "description": "Publish application-specific Prometheus metrics alongside built-in observability.", "tags": ["Observability", "Metrics"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-custom-metrics" }, + { "title": "HTTP Service Communication", "description": "Make inter-service HTTP calls with circuit breaker and retry support.", "tags": ["Communication", "Resilience"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-http-service" }, + { "title": "Auth Middleware", "description": "Protect endpoints with Basic Auth, API Key, or OAuth middleware.", "tags": ["Security", "Middleware"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-http-auth-middleware" }, + { "title": "File Handling", "description": "Upload, download, and manage files with local, S3, GCS, or FTP backends.", "tags": ["Files", "Storage"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-add-filestore" }, + { "title": "File Binding", "description": "Bind uploaded files directly to structs for type-safe file processing.", "tags": ["Files", "Data Binding"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-file-bind" }, + { "title": "HTML Templates", "description": "Serve server-rendered HTML pages with Go template support.", "tags": ["Templates", "Frontend"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/using-html-template" }, + { "title": "CLI Application", "description": "Build command-line tools with subcommands, flags, and structured output.", "tags": ["CLI", "Tools"], "href": "https://github.com/gofr-dev/gofr/tree/main/examples/sample-cmd" } +] diff --git a/src/app/examples/layout.jsx b/src/app/examples/layout.jsx new file mode 100644 index 0000000..3df491d --- /dev/null +++ b/src/app/examples/layout.jsx @@ -0,0 +1,27 @@ +import React from 'react' + +export const metadata = { + title: 'GoFr Examples — REST, gRPC, Pub/Sub, GraphQL, WebSocket', + description: + 'Real-world GoFr examples covering REST APIs, gRPC, Pub/Sub (Kafka, NATS, Google Pub/Sub), GraphQL, WebSockets, cron jobs, migrations, observability, and more.', + metadataBase: new URL('https://gofr.dev'), + alternates: { canonical: '/examples' }, + openGraph: { + type: 'website', + url: 'https://gofr.dev/examples', + title: 'GoFr Examples — REST, gRPC, Pub/Sub, GraphQL, WebSocket', + description: + 'Runnable Go microservice examples: REST, gRPC, Pub/Sub, GraphQL, WebSocket, cron, migrations, observability.', + images: [{ url: '/opengraph-image.png', width: 1200, height: 630 }], + }, + twitter: { + card: 'summary_large_image', + site: '@gofr_dev', + title: 'GoFr Examples', + description: 'Runnable Go microservice examples covering all major patterns.', + images: ['/twitter-image.png'], + }, +} + +const Layout = ({ children }) => children +export default Layout diff --git a/src/app/examples/page.jsx b/src/app/examples/page.jsx new file mode 100644 index 0000000..e02fe8d --- /dev/null +++ b/src/app/examples/page.jsx @@ -0,0 +1,178 @@ +'use client' + +import { useState } from 'react' +import Link from 'next/link' +import examples from './examples.json' + +const tagColors = { + 'REST': 'bg-emerald-500/10 text-emerald-400', + 'gRPC': 'bg-violet-500/10 text-violet-400', + 'Pub/Sub': 'bg-sky-500/10 text-sky-400', + 'Messaging': 'bg-sky-500/10 text-sky-400', + 'Database': 'bg-amber-500/10 text-amber-400', + 'Redis': 'bg-red-500/10 text-red-400', + 'Communication': 'bg-blue-500/10 text-blue-400', + 'Migrations': 'bg-amber-500/10 text-amber-400', + 'GraphQL': 'bg-pink-500/10 text-pink-400', + 'WebSocket': 'bg-indigo-500/10 text-indigo-400', + 'Background': 'bg-slate-500/10 text-slate-400', + 'Scheduling': 'bg-slate-500/10 text-slate-400', + 'Observability': 'bg-cyan-500/10 text-cyan-400', + 'Metrics': 'bg-cyan-500/10 text-cyan-400', + 'Resilience': 'bg-orange-500/10 text-orange-400', + 'Security': 'bg-red-500/10 text-red-400', + 'Middleware': 'bg-purple-500/10 text-purple-400', + 'Files': 'bg-teal-500/10 text-teal-400', + 'Storage': 'bg-teal-500/10 text-teal-400', + 'Data Binding': 'bg-lime-500/10 text-lime-400', + 'Templates': 'bg-rose-500/10 text-rose-400', + 'Frontend': 'bg-rose-500/10 text-rose-400', + 'CLI': 'bg-slate-500/10 text-slate-300', + 'Tools': 'bg-slate-500/10 text-slate-400', + 'Getting Started': 'bg-emerald-500/10 text-emerald-400', +} + +const allTags = [...new Set(examples.flatMap((e) => e.tags))] + +export default function ExamplesPage() { + let [activeTag, setActiveTag] = useState(null) + + let filtered = activeTag + ? examples.filter((e) => e.tags.includes(activeTag)) + : examples + + let featured = examples.filter((e) => e.featured) + + return ( +
    +
    +
    +

    + Examples & Recipes +

    +

    + Learn GoFr by example. Each recipe is a working project you can clone and run. +

    + {/* Quick clone snippet — answers the "ok how do I run these?" question */} + {/* immediately, without making the visitor hunt for instructions. */} +
    +
    + $ + {/* whitespace-nowrap so the command never breaks mid-word; */} + {/* the code element scrolls horizontally if it's too long. */} + + git clone https://github.com/gofr-dev/gofr + + + + + + + Codespaces + +
    +

    + Examples live under gofr/examples — pick any subfolder and run go run main.go. +

    +
    +
    + + {/* Featured */} + {!activeTag && ( +
    +

    + Start here +

    +
    + {featured.map((example) => ( + +
    +
    +

    {example.title}

    +

    {example.description}

    +
    + {example.tags.map((tag) => ( + + {tag} + + ))} +
    +
    + + ))} +
    +
    + )} + + {/* Tag filter */} +
    + + {allTags.map((tag) => ( + + ))} +
    + + {/* All examples */} +
    + {filtered.map((example) => ( + +
    +
    +

    {example.title}

    +

    {example.description}

    +
    + {example.tags.map((tag) => ( + + {tag} + + ))} +
    +
    + + ))} +
    + + {/* CTA */} +
    + + Browse all examples on GitHub → + +
    +
    +
    + ) +} diff --git a/src/app/faq/layout.jsx b/src/app/faq/layout.jsx new file mode 100644 index 0000000..af09d65 --- /dev/null +++ b/src/app/faq/layout.jsx @@ -0,0 +1,5 @@ +import { MarketingPage } from '@/components/MarketingPage' + +const Layout = ({ children }) => {children} + +export default Layout diff --git a/src/app/layout.jsx b/src/app/layout.jsx index 280c313..a1d1fea 100644 --- a/src/app/layout.jsx +++ b/src/app/layout.jsx @@ -22,6 +22,73 @@ const lexend = localFont({ variable: '--font-lexend', }) +// Site-wide defaults. Per-route metadata (page.jsx `metadata` exports +// or Markdoc `nextjs.metadata` frontmatter) overrides the title / +// description / openGraph.{title,description,url} on a per-page basis; +// site-wide values like the social image, the Twitter handles, and +// type=website inherit through unless explicitly overridden. +// +// Important: this used to be hardcoded as tags inside the +// JSX, which silently overrode every per-page metadata setting +// — every subpage was sharing the home page's social card. Moving it +// into the metadata export lets Next's metadata-merge actually do its +// job. +export const metadata = { + metadataBase: new URL('https://gofr.dev'), + title: { + default: 'GoFr — An Opinionated Go Framework', + template: '%s | GoFr', + }, + description: + 'An Opinionated Go Framework for accelerated microservice development. Built-in observability, 15+ datasources, gRPC, GraphQL, WebSockets, and pub/sub.', + // Canonical intentionally omitted from the root layout — setting it + // to '/' would brand every subpage as a duplicate of the home page. + // Per-page metadata sets its own canonical via `alternates.canonical` + // (or via Next's URL-based default when metadataBase is set). + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + 'max-snippet': -1, + 'max-image-preview': 'large', + 'max-video-preview': -1, + }, + }, + openGraph: { + type: 'website', + siteName: 'GoFr', + title: 'GoFr — An Opinionated Go Framework', + description: + 'An Opinionated Go Framework for accelerated microservice development. Built-in observability, 15+ datasources, gRPC, GraphQL, WebSockets, and pub/sub.', + url: 'https://gofr.dev/', + images: [ + { + url: '/opengraph-image.png', + width: 1200, + height: 630, + alt: 'GoFr — An Opinionated Go Framework', + }, + ], + }, + twitter: { + card: 'summary_large_image', + site: '@gofr_dev', + creator: '@gofr_dev', + title: 'GoFr — An Opinionated Go Framework', + description: + 'An Opinionated Go Framework for accelerated microservice development. Built-in observability, 15+ datasources, gRPC, GraphQL, WebSockets, and pub/sub.', + images: ['/twitter-image.png'], + }, + verification: { + google: [ + 'MVkGpVWwO1qPJIoXAKXQs5b6oKwxLAMLWtDDMeD23hE', + '9TFTpJ19XHm0dVVKTF5l6OTMLcahEn0M3aZFZ14gRFI', + ], + }, +} + export default function RootLayout({ children }) { return ( - - - - - - + {/* AI / LLM discoverability. Two signals every page emits: */} + {/* - `rel="alternate"` with text/plain + text/markdown so */} + {/* crawlers that follow rel-alternate links pick them up. */} + {/* - The original "ai" + "llm" rel values are not yet a W3C */} + {/* standard but match the convention emerging across sites */} + {/* that have published llms.txt — costs nothing to emit. */} + {/* The hreflang on rel="alternate" is intentionally omitted */} + {/* because these resources are language-neutral indexes. */} + + + + + - {/* -