Skip to content

Commit

Permalink
Merge pull request #1327 from gofr-dev/release/1.29.0
Browse files Browse the repository at this point in the history
Release/1.29.0
  • Loading branch information
vipul-rawat authored Dec 24, 2024
2 parents 16de8ae + a6c406f commit 5bc6ec2
Show file tree
Hide file tree
Showing 40 changed files with 733 additions and 319 deletions.
62 changes: 60 additions & 2 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: ['1.22', '1.21']
go-version: ['1.23', '1.22']

services:
kafka:
Expand Down Expand Up @@ -157,6 +157,53 @@ jobs:
# codeCoverage=${{ env.CODE_COVERAGE }}
# codeCoverage=${codeCoverage%??}
# if [[ $codeCoverage -lt 92 ]]; then echo "code coverage cannot be less than 92%, currently its ${{ env.CODE_COVERAGE }}%" && exit 1; fi;
Submodule-Unit-Testing:
name: Submodule Unit Testing (v${{ matrix.go-version }})🛠
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ '1.23', '1.22' ]

steps:
- name: Checkout code into go module directory
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
id: Go

- name: Detect and Test Submodules
run: |
# Find all directories containing a go.mod file within 'pkg'
for module in $(find pkg -name "go.mod" -exec dirname {} \;); do
echo "Testing module: $module"
cd $module
# Extract module name (replace '/' with '_')
module_name=$(echo $module | tr '/' '_')
# Download dependencies for the submodule
go mod download
go mod tidy
# Run tests for the submodule and generate coverage
export APP_ENV=test
go test ./... -v -short -coverprofile=${module_name}.cov -coverpkg=./...
# Return to the root directory
cd -
done
- name: Upload Coverage Reports
uses: actions/upload-artifact@v3
with:
name: coverage-reports
path: pkg/**/*.cov


upload_coverage:
name: Upload Coverage📊
Expand Down Expand Up @@ -195,9 +242,20 @@ jobs:
uses: actions/checkout@v4
- name: Get dependencies
run: go get -v -t -d ./...
- name: GolangCI-Lint
- name: Lint Root Module
run: |
echo "Linting root module..."
golangci-lint run --timeout 9m0s
- name: Lint Submodules
run: |
echo "Searching for submodules..."
for module in $(find pkg -name "go.mod" -exec dirname {} \;); do
echo "Linting submodule: $module"
cd $module
go mod tidy
golangci-lint run --timeout 9m0s
cd -
done
linting_party:
name: Linting Party🥳
Expand Down
6 changes: 6 additions & 0 deletions docs/advanced-guide/gofr-errors/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ dbErr2 := datasource.ErrorDB{Message : "database connection timed out!"}
GoFr's error structs implements an interface with `Error() string` and `StatusCode() int` methods, users can override the
status code by implementing it for their custom error.

You can optionally define a log level for your error with the `LogLevel() logging.Level` methods

#### Usage:
```go
type customError struct {
Expand All @@ -57,4 +59,8 @@ func (c customError) Error() string {
func (c customError) StatusCode() int {
return http.StatusMethodNotAllowed
}

func (c customError) LogLevel() logging.Level {
return logging.WARN
}
```
128 changes: 95 additions & 33 deletions docs/advanced-guide/setting-custom-response-headers/page.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,118 @@
# Setting Custom Response Headers
# Custom Response Headers and Metadata in GoFr

In GoFr, you can customize HTTP response headers using the `Response` struct, allowing you to add extra information to
responses sent from your application. This feature can be useful for adding metadata, such as custom headers, security
policies, or other contextual information, to improve the client-server communication.
GoFr simplifies the process of adding custom HTTP response headers and metadata to API responses using the `Response` struct. This feature allows you to include additional information such as custom headers or metadata to enhance client-server communication while keeping your data payload clean and structured.

## Using the Response Struct
## Features

To use custom headers in your handler, create and return a Response object within the handler function. This object
should contain the response data along with a Headers map for any custom headers you wish to add.
1. **Custom Headers**: Add key-value pairs for headers, useful for:
- Security policies
- Debugging information
- Versioning details

### Example:
**Type**: `map[string]string`
- Keys and values must be strings.

Below is an example showing how to use the Response struct in a GoFr handler. In this case, the `HelloHandler` function
returns a greeting message along with two custom headers: X-Custom-Header and X-Another-Header.
2. **Metadata**: Include optional contextual information like:
- Deployment environment
- Request-specific details (e.g., timestamps, tracing IDs)

**Type**: `map[string]any`
- Keys must be strings, and values can be of any type.

When metadata is included, the response structure is:
```json
{
"data": {},
"metadata": {}
}
```

If metadata is omitted, the response defaults to:

```json
{
"data": {}
}
```

### Example Usage

#### Adding Custom Headers and Metadata
To include custom headers and metadata in your response, populate the Headers and MetaData fields of the Response struct in your handler function.

```go
package main

import (
"gofr.dev/pkg/gofr"
"gofr.dev/pkg/gofr/http/response"
"time"

"gofr.dev/pkg/gofr"
"gofr.dev/pkg/gofr/http/response"
)

func main() {
// Create a new application
a := gofr.New()
app := gofr.New()

// Add the route
a.GET("/hello", HelloHandler)
app.GET("/hello", HelloHandler)

// Run the application
a.Run()
app.Run()
}

func HelloHandler(c *gofr.Context) (interface{}, error) {
name := c.Param("name")
if name == "" {
c.Log("Name came empty")
name = "World"
}

headers := map[string]string{
"X-Custom-Header": "CustomValue",
"X-Another-Header": "AnotherValue",
}

return response.Response{
Data: "Hello World from new Server",
Headers: headers,
}, nil
name := c.Param("name")
if name == "" {
c.Log("Name parameter is empty, defaulting to 'World'")
name = "World"
}

// Define custom headers (map[string]string)
headers := map[string]string{
"X-Custom-Header": "CustomValue",
"X-Another-Header": "AnotherValue",
}

// Define metadata (map[string]any)
metaData := map[string]any{
"environment": "staging",
"timestamp": time.Now(),
}

// Return response with custom headers and metadata
return response.Response{
Data: map[string]string{"message": "Hello, " + name + "!"},
Metadata: metaData,
Headers: headers,
}, nil
}
```

### Example Responses
#### Response with Metadata:
When metadata is included, the response contains the metadata field:

```json
{
"data": {
"message": "Hello, World!"
},
"metadata": {
"environment": "staging",
"timestamp": "2024-12-23T12:34:56Z"
}
}
```

#### Response without Metadata:
If no metadata is provided, the response only includes the data field:

```json
{
"data": {
"message": "Hello, World!"
}
}
```


This functionality offers a convenient, structured way to include additional response information without altering the
core data payload.
2 changes: 2 additions & 0 deletions docs/quick-start/connecting-redis/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ Following configuration keys are required for Redis connectivity:
* `REDIS_PORT`: It specifies the port number on which your Redis server is listening. The default Redis port is 6379.
* `REDIS_USER` : This is the user you'll use to connect to your Redis server. You can configure multiple users with different permissions in a single Redis container. For more details, refer to the [official docs](https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/)
* `REDIS_PASSWORD`: The password is required only if your Redis server is configured for authentication; if authentication is not enabled, no password is necessary.
* `REDIS_DB`: The database number to use for the Redis server. The default value is 0.
```dotenv
APP_NAME=test-service
HTTP_PORT=9000
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=password
REDIS_DB=2
```

The following code snippet demonstrates how to retrieve data from a Redis key named "greeting":
Expand Down
33 changes: 33 additions & 0 deletions docs/references/configs/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,21 @@ This document lists all the configuration options supported by the GoFr framewor
- REDIS_PORT
- Port of the Redis server.

---

- REDIS_USER
- Username for the Redis server.

---

- REDIS_PASSWORD
- Password for the Redis server.

---

- REDIS_DB
- Database number to use for the Redis server.

{% /table %}

### Pub/Sub
Expand Down Expand Up @@ -253,6 +268,24 @@ This document lists all the configuration options supported by the GoFr framewor

---

- KAFKA_BATCH_SIZE
- Number of messages to batch before sending to Kafka
- 1

---

- KAFKA_BATCH_BYTES
- Number of bytes to batch before sending to Kafka
- 1048576

---

- KAFKA_BATCH_TIMEOUT
- Time to wait before sending a batch to Kafka
- 100ms

---

- CONSUMER_ID
- Unique identifier for this consumer
- gofr-consumer
Expand Down
10 changes: 5 additions & 5 deletions examples/using-add-filestore/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect
go.opentelemetry.io/otel/trace v1.32.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/net v0.31.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/term v0.26.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.8.0 // indirect
google.golang.org/api v0.209.0 // indirect
google.golang.org/genproto v0.0.0-20241113202542-65e8d215514f // indirect
Expand Down
20 changes: 10 additions & 10 deletions examples/using-add-filestore/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
Expand Down Expand Up @@ -293,8 +293,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -309,24 +309,24 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
Loading

0 comments on commit 5bc6ec2

Please sign in to comment.