Skip to content

Commit aae16f3

Browse files
committed
Merge remote-tracking branch 'origin' into en/rate_limiter
2 parents 71d4f72 + 46406c0 commit aae16f3

File tree

84 files changed

+4135
-564
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+4135
-564
lines changed

docs/advanced-guide/grpc/page.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,31 @@ func authInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, h
194194
}
195195
```
196196

197+
## Adding Custom Stream interceptors
198+
199+
For streaming RPCs (client-stream, server-stream, or bidirectional), GoFr allows you to add stream interceptors using AddGRPCServerStreamInterceptors. These are useful for handling logic that needs to span the entire lifetime of a stream.
200+
```go
201+
func main() {
202+
app := gofr.New()
203+
204+
app.AddGRPCServerStreamInterceptors(streamAuthInterceptor)
205+
206+
// ... register your service
207+
app.Run()
208+
}
209+
210+
func streamAuthInterceptor(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
211+
// Example: Validate metadata for the entire stream
212+
md, ok := metadata.FromIncomingContext(ss.Context())
213+
if !ok || !isValidToken(md["auth-token"]) {
214+
return status.Errorf(codes.Unauthenticated, "invalid stream token")
215+
}
216+
217+
// If valid, continue processing the stream
218+
return handler(srv, ss)
219+
}
220+
```
221+
197222
For more details on adding additional interceptors and server options, refer to the [official gRPC Go package](https://pkg.go.dev/google.golang.org/grpc#ServerOption).
198223

199224
## Generating gRPC Client using `gofr wrap grpc client`
@@ -229,7 +254,48 @@ func {serviceMethod}(ctx *gofr.Context) (*{serviceResponse}, error) {
229254
return res, nil
230255
}
231256
```
257+
## Error Handling and Validation
258+
GoFr's gRPC implementation includes built-in error handling and validation:
259+
260+
**Port Validation**: Automatically validates that gRPC ports are within valid range (1-65535)
261+
**Port Availability**: Checks if the specified port is available before starting the server
262+
**Server Creation**: Validates server creation and provides detailed error messages
263+
**Container Injection**: Validates container injection into gRPC services with detailed logging
264+
265+
Port Configuration
266+
```bash
267+
// Set custom gRPC port in .env file
268+
GRPC_PORT=9001
269+
270+
// Or use default port 9000 if not specified
271+
```
272+
## gRPC Reflection
273+
GoFr supports gRPC reflection for easier debugging and testing. Enable it using the configuration:
274+
```bash
275+
# In your .env file
276+
GRPC_ENABLE_REFLECTION=true
277+
```
278+
When enabled, you can use tools like grpcurl to inspect and test your gRPC services:
279+
280+
```bash
281+
# List available services
282+
grpcurl -plaintext localhost:9000 list
283+
284+
# Describe a service
285+
grpcurl -plaintext localhost:9000 describe YourService
286+
287+
# Make a test call
288+
grpcurl -plaintext -d '{"name": "test"}' localhost:9000 YourService/YourMethod
289+
```
290+
291+
## Built-in Metrics
292+
GoFr automatically registers the following gRPC metrics:
293+
294+
+ **grpc_server_status**: Gauge indicating server status (1=running, 0=stopped)
295+
+ **grpc_server_errors_total**: Counter for total gRPC server errors
296+
+ **grpc_services_registered_total**: Counter for total registered gRPC services
232297
298+
These metrics are automatically available in your metrics endpoint and can be used for monitoring and alerting.
233299
234300
## Customizing gRPC Client with DialOptions
235301

docs/advanced-guide/overriding-default/page.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ func main() {
143143
}
144144
```
145145

146+
In GoFr, the following HTTP methods can be redirected, along with their corresponding status codes:
147+
148+
- **GET (302 Found)**: It is safe to redirect because the request remains a GET after the redirect.
149+
- **POST (303 See Other)**: The browser converts the POST request to a GET on redirect.
150+
- **PUT (303 See Other)**: The browser converts the PUT request to a GET on redirect.
151+
- **PATCH (303 See Other)**: The browser converts the PATCH request to a GET on redirect.
152+
- **DELETE (302 Found)**: This is a temporary redirect, but method handling is ambiguous, as most browsers historically convert the DELETE request into a GET.
153+
154+
146155
## Favicon.ico
147156

148157
By default, GoFr loads its own `favicon.ico` present in root directory for an application. To override `favicon.ico` user

docs/cli/cli.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# CLI Applications
2+
3+
GoFr provides a simple way to build command-line applications using `app.NewCMD()`. This creates standalone CLI tools without starting an HTTP server.
4+
5+
## Getting Started
6+
7+
Create a basic CLI application with subcommands:
8+
9+
```go
10+
package main
11+
12+
import (
13+
"fmt"
14+
"gofr.dev/pkg/gofr"
15+
)
16+
17+
func main() {
18+
app := gofr.NewCMD()
19+
20+
// Simple hello command
21+
app.SubCommand("hello", func(c *gofr.Context) (any, error) {
22+
return "Hello World!", nil
23+
}, gofr.AddDescription("Print hello message"))
24+
25+
// Command with parameters
26+
app.SubCommand("greet", func(c *gofr.Context) (any, error) {
27+
name := c.Param("name")
28+
if name == "" {
29+
name = "World"
30+
}
31+
return fmt.Sprintf("Hello, %s!", name), nil
32+
})
33+
34+
app.Run()
35+
}
36+
```
37+
38+
## Key GoFr CLI Methods
39+
40+
- **`app.NewCMD()`**: Initialize a CLI application
41+
- **`app.SubCommand(name, handler, options...)`**: Add a subcommand
42+
- **`gofr.AddDescription(desc)`**: Add help description
43+
- **`gofr.AddHelp(help)`**: Add detailed help text
44+
- **`ctx.Param(name)`**: Get command parameters
45+
- **`ctx.Out.Println()`**: Print to stdout
46+
- **`ctx.Logger`**: Access logging
47+
48+
## Running CLI Applications
49+
50+
Build and run your CLI:
51+
52+
```bash
53+
go build -o mycli
54+
./mycli hello
55+
./mycli greet --name John
56+
./mycli --help
57+
```
58+
59+
## Example Commands
60+
61+
```bash
62+
# Basic command
63+
./mycli hello
64+
# Output: Hello World!
65+
66+
# Command with parameter
67+
./mycli greet --name Alice
68+
# Output: Hello, Alice!
69+
70+
# Help
71+
./mycli --help
72+
```
73+
74+
For more details, see the [sample-cmd example](../../examples/sample-cmd).

docs/datasources/arangodb/page.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
## ArangoDB
1+
# ArangoDB
2+
3+
4+
5+
## Configuration
6+
7+
To connect to `ArangoDB`, you need to provide the following environment variables:
8+
- `HOST`: The hostname or IP address of your `ArangoDB` server.
9+
- `USER`: The username for connecting to the database.
10+
- `PASSWORD`: The password for the specified user.
11+
- `PORT`: The port number
12+
13+
## Setup
214

315
GoFr supports injecting `ArangoDB` that implements the following interface. Any driver that implements the interface can be
416
added using the `app.AddArangoDB()` method, and users can use ArangoDB across the application with `gofr.Context`.
@@ -47,14 +59,13 @@ Import the GoFr's external driver for ArangoDB:
4759
go get gofr.dev/pkg/gofr/datasource/arangodb@latest
4860
```
4961

50-
### Example
62+
## Example
5163

5264
```go
5365
package main
5466

5567
import (
5668
"fmt"
57-
5869
"gofr.dev/pkg/gofr"
5970
"gofr.dev/pkg/gofr/datasource/arangodb"
6071
)
@@ -69,10 +80,10 @@ func main() {
6980

7081
// Configure the ArangoDB client
7182
arangoClient := arangodb.New(arangodb.Config{
72-
Host: "localhost",
73-
User: "root",
74-
Password: "root",
75-
Port: 8529,
83+
Host: app.Config.Get("HOST"),
84+
User: app.Config.Get("USER"),
85+
Password: app.Config.Get("PASSWORD"),
86+
Port: app.Config.Get("PORT"),
7687
})
7788
app.AddArangoDB(arangoClient)
7889

@@ -193,4 +204,4 @@ func GetEdgesHandler(ctx *gofr.Context) (any, error) {
193204
"edges": edges,
194205
}, nil
195206
}
196-
```
207+
```

docs/datasources/cassandra/page.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
## Cassandra
1+
# Cassandra
2+
GoFr supports pluggable Cassandra drivers.
23

3-
GoFr supports pluggable Cassandra drivers. It defines an interface that specifies the required methods for interacting
4+
## Configuration
5+
To connect to `Cassandra`, you need to provide the following environment variables:
6+
7+
- `HOSTS`: The hostname or IP address of your Cassandra server.
8+
- `KEYSPACE`: The name of the keyspace (like a database) that holds your tables and defines replication and durability settings.
9+
- `PORT`: The port number
10+
- `USERNAME`: The username for connecting to the database.
11+
- `PASSWORD`: The password for the specified user.
12+
13+
14+
## Setup
15+
16+
GoFr defines an interface that specifies the required methods for interacting
417
with Cassandra. Any driver implementation that adheres to this interface can be integrated into GoFr using the
518
`app.AddCassandra()` method. This approach promotes flexibility and allows you to choose the Cassandra driver that best
619
suits your project's needs.
720

21+
822
```go
923
type CassandraWithContext interface {
1024
QueryWithCtx(ctx context.Context, dest any, stmt string, values ...any) error
@@ -59,11 +73,11 @@ func main() {
5973
app := gofr.New()
6074

6175
config := cassandraPkg.Config{
62-
Hosts: "localhost",
63-
Keyspace: "test",
64-
Port: 2003,
65-
Username: "cassandra",
66-
Password: "cassandra",
76+
Hosts: app.Config.Get("HOSTS"),
77+
Keyspace: app.Config.Get("KEYSPACE"),
78+
Port: app.Config.Get("PORT"),
79+
Username: app.Config.Get("USERNAME"),
80+
Password: app.Config.Get("PASSWORD"),
6781
}
6882

6983
cassandra := cassandraPkg.New(config)
@@ -97,4 +111,4 @@ func main() {
97111

98112
app.Run()
99113
}
100-
```
114+
```

docs/datasources/clickhouse/page.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
## ClickHouse
1+
# ClickHouse
22

3+
## Configuration
4+
To connect to `ClickHouse`, you need to provide the following environment variables and use it:
5+
- `HOSTS`: The hostname or IP address of your `ClickHouse` server.
6+
- `USERNAME`: The username for connecting to the database.
7+
- `PASSWORD`: The password for the specified user.
8+
- `DATABASE`: The name of the database to connect to.
9+
10+
11+
## Setup
312
GoFr supports injecting ClickHouse that supports the following interface. Any driver that implements the interface can be added
413
using `app.AddClickhouse()` method, and user's can use ClickHouse across application with `gofr.Context`.
514
```go
@@ -38,10 +47,10 @@ func main() {
3847
app := gofr.New()
3948

4049
app.AddClickhouse(clickhouse.New(clickhouse.Config{
41-
Hosts: "localhost:9001",
42-
Username: "root",
43-
Password: "password",
44-
Database: "users",
50+
Hosts: app.Config.Get("HOSTS"),
51+
Username: app.Config.Get("USERNAME"),
52+
Password: app.Config.Get("PASSWORD"),
53+
Database: app.Config.Get("DATABASE"),
4554
}))
4655

4756
app.POST("/user", Post)
@@ -69,4 +78,4 @@ func Get(ctx *gofr.Context) (any, error) {
6978

7079
return user, nil
7180
}
72-
```
81+
```

docs/datasources/couchbase/page.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
## Couchbase
1+
# Couchbase
2+
3+
## Configuration
4+
5+
To connect to `Couchbase`, you need to provide the following environment variables and use it:
6+
- `HOST`: The hostname or IP address of your Couchbase server.
7+
- `USER`: The username for connecting to the database.
8+
- `PASSWORD`: The password for the specified user.
9+
- `BUCKET`: Top level container
10+
11+
## Setup
212

313
GoFr supports injecting `Couchbase` that implements the following interface. Any driver that implements the interface can be
414
added using the `app.AddCouchbase()` method, and users can use Couchbase across the application with `gofr.Context`.
@@ -38,7 +48,6 @@ import (
3848
"context"
3949
"fmt"
4050
"log"
41-
4251
"gofr.dev/pkg/gofr"
4352
"gofr.dev/pkg/gofr/datasource/couchbase"
4453
)
@@ -55,10 +64,10 @@ func main() {
5564

5665
// Add the Couchbase datasource to the application
5766
a.AddCouchbase(couchbase.New(&couchbase.Config{
58-
Host: "localhost",
59-
User: "Administrator",
60-
Password: "password",
61-
Bucket: "test-bucket",
67+
Host: app.Config.Get("HOST"),
68+
User: app.Config.Get("USER"),
69+
Password: app.Config.Get("PASSWORD"),
70+
Bucket: app.Config.Get("BUCKET"),
6271
}))
6372

6473
// Add the routes

docs/datasources/dgraph/page.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
## Dgraph
1+
# Dgraph
22

3+
## Configuration
4+
To connect to `Dgraph`, you need to provide the following environment variables and use it:
5+
- `HOST`: The hostname or IP address of your Dgraph server.
6+
- `PORT`: The port number.
7+
8+
## Setup
39
GoFr supports injecting Dgraph with an interface that defines the necessary methods for interacting with the Dgraph
410
database. Any driver that implements the following interface can be added using the app.AddDgraph() method.
511

@@ -55,7 +61,6 @@ package main
5561
import (
5662
"encoding/json"
5763
"fmt"
58-
5964
"github.com/dgraph-io/dgo/v210/protos/api"
6065

6166
"gofr.dev/pkg/gofr"
@@ -67,8 +72,8 @@ func main() {
6772
app := gofr.New()
6873

6974
db := dgraph.New(dgraph.Config{
70-
Host: "localhost",
71-
Port: "9080",
75+
Host: app.Config.Get("HOST"),
76+
Port: app.Config.Get("PORT"),
7277
})
7378

7479
// Connect to Dgraph running on localhost:9080
@@ -136,4 +141,4 @@ func DGraphQueryHandler(c *gofr.Context) (any, error) {
136141

137142
return result, nil
138143
}
139-
```
144+
```

0 commit comments

Comments
 (0)