Skip to content

Commit 95da216

Browse files
srijan-27Umang01-hashdependabot[bot]rokerzfirst101vikash
authored
Release v1.3.0 (#443)
* Create pull_request_template.md * Rename pull_request_template.md to .github/pull_request_template.md * convert microseconds to milliseconds in logs * add env support for diff environments. (#403) * Bump google.golang.org/api from 0.171.0 to 0.172.0 (#414) * Bump github.com/go-sql-driver/mysql from 1.8.0 to 1.8.1 (#413) * remove error for .local.env * refactor if statement * Update README.md * change datasources as interface in container (#426) * have a len check instead of len check for subscriptions (#436) * add README.md for using-file-bind example (#439) * Fix/documentation (#438) * updated the docs * log errors as well when migrations are rolled back * add version in Migration rolled back log * update health check URL in docs and add documentation for supporting diff envirnoment for configs * fix ports and remove unused commands in contributing.md * refactor configurations doc * add docs for connecting to different sql db dialects * Update go.yml kafka port * fix build fail for configuration quick start * revert port change for kafka --------- Co-authored-by: Raramuri <[email protected]> Co-authored-by: mehrotra234 <[email protected]> Co-authored-by: Aryan Mehrotra <[email protected]> Co-authored-by: Vipul Rawat <[email protected]> * [EN] Refactor Migrations (#412) * Externalize mongo (#435) * add Mongo interface * add Logger to app * modify Mongo interface * add godoc and web doc * add nav for injecting-database-drivers --------- Co-authored-by: Srijan Rastogi <[email protected]> * Remove mock_datasource from test coverage (#441) --------- Co-authored-by: Raramuri <[email protected]> * Add CRUD from struct (#406) * initial commit * add DELETE handler functionality * restructure code and refactor code parts * separate out code in file crud_from_struct * refactor code * resolve some of the linters * add GetAll and Put implementations * resolve linters * create struct entityConfig for getting entity info * fix duplicate entity resp in getall * add method verifyHandlerSignature to verify overriding of handlers * add comments and rename file to crud_hanlers.go * refactor implementation with interface * update example for crud * update readme | add integration tests * update branch * add migration for user table * change migration name to timestamp * fix migrations versioning * fix test | add log | fix linters * add test for delete handler * fix test | add log | fix linters * add test for Get, Delete and Patch Handler * resolve linters and add test for create and getall handlers * add docs for crud from struct * refactoring vars & docs * refactor NewEmptyContainer with NewContainer * change method name from CRUDFromStruct to AddRESTHandlers * update docs with AddRESTHandlers * fix tests | review comments --------- Co-authored-by: umang01-hash <[email protected]> * update framework version to v1.3.0 --------- Co-authored-by: Umang Mundhra <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: rokerzfirst101 <[email protected]> Co-authored-by: Vikash Kumar <[email protected]> Co-authored-by: Vipul Rawat <[email protected]> Co-authored-by: Raramuri <[email protected]> Co-authored-by: mehrotra234 <[email protected]> Co-authored-by: Aryan Mehrotra <[email protected]>
1 parent fbe79af commit 95da216

File tree

64 files changed

+9470
-804
lines changed

Some content is hidden

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

64 files changed

+9470
-804
lines changed

.github/pull_request_template.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Pull Request Template
2+
3+
4+
**Description:**
5+
6+
- Provide a concise explanation of the changes made.
7+
- Mention the issue number(s) this PR addresses (if applicable).
8+
- Highlight the motivation behind the changes and the expected benefits.
9+
10+
11+
**Breaking Changes (if applicable):**
12+
13+
- List any breaking changes introduced by this PR.
14+
- Explain the rationale behind these changes and how they will impact users.
15+
16+
**Additional Information:**
17+
18+
- Mention any relevant dependencies or external libraries used.
19+
- Include screenshots or code snippets (if necessary) to clarify the changes.
20+
21+
**Checklist:**
22+
23+
- [ ] I have formatted my code using `goimport` and `golangci-lint`.
24+
- [ ] All new code is covered by unit tests.
25+
- [ ] This PR does not decrease the overall code coverage.
26+
- [ ] I have reviewed the code comments and documentation for clarity.
27+
28+
**Thank you for your contribution!**
29+

.github/workflows/go.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
4141
- name: Test
4242
run: |
43-
export GOFR_ENV=test
43+
export APP_ENV=test
4444
go test gofr.dev/pkg/gofr/migration... -v -short -coverprofile profile.cov -coverpkg=gofr.dev/pkg/gofr/migration...
4545
4646
go tool cover -func profile.cov
@@ -113,7 +113,7 @@ jobs:
113113

114114
- name: Test
115115
run: |
116-
export GOFR_ENV=test
116+
export APP_ENV=test
117117
go test gofr.dev/examples/... -v -short -coverprofile packageWithpbgo.cov -coverpkg=gofr.dev/examples/...
118118
grep -vE '^gofr\.dev\/.*\.pb\.go' packageWithpbgo.cov > profile.cov
119119
go tool cover -func profile.cov
@@ -150,10 +150,12 @@ jobs:
150150
151151
- name: Test
152152
run: |
153-
export GOFR_ENV=test
153+
export APP_ENV=test
154154
go test gofr.dev/pkg/... -tags migration -v -short -coverprofile packageWithMigration.cov -coverpkg=gofr.dev/pkg/...
155155
grep -v 'gofr.dev/pkg/gofr/migration' packageWithMigration.cov > packageWithoutMigration.cov
156-
grep -v 'google/mock_interfaces\.go' packageWithoutMigration.cov > profile.cov
156+
grep -v 'gofr.dev/pkg/gofr/migration/mock_datasources.go' packageWithoutMigration.cov > packageWithoutMockMigrationDatasource.cov
157+
grep -v 'gofr.dev/pkg/gofr/container/mock_datasources.go' packageWithoutMockMigrationDatasource.cov > packageWithoutMockDatasource.cov
158+
grep -v 'google/mock_interfaces\.go' packageWithoutMockDatasource.cov > profile.cov
157159
go tool cover -func profile.cov
158160
159161
- name: Upload Test Coverage
@@ -236,4 +238,4 @@ jobs:
236238
run: go get -v -t -d ./...
237239
- name: GolangCI-Lint
238240
run: |
239-
golangci-lint run --timeout 9m0s
241+
golangci-lint run --timeout 9m0s

CONTRIBUTING.md

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,18 @@ Some services will be required to pass the entire test suite. We recommend using
5353

5454
docker run --name gofr-mysql -e MYSQL_ROOT_PASSWORD=password -p 2001:3306 -d mysql:8.0.30
5555
docker run --name gofr-redis -p 2002:6379 -d redis:7.0.5
56-
docker run --name gofr-cassandra -d -p 2003:9042 cassandra:4.1
57-
docker run --name gofr-solr -p 2020:8983 solr:8 -DzkRun
58-
docker run --name gofr-mongo -d -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin123 -p 2004:27017 mongo:6.0.2
5956
docker run --name gofr-zipkin -d -p 2005:9411 openzipkin/zipkin:2
6057
docker run --name gofr-pgsql -d -e POSTGRES_DB=customers -e POSTGRES_PASSWORD=root123 -p 2006:5432 postgres:15.1
6158
docker run --name gofr-mssql -d -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=reallyStrongPwd123' -p 2007:1433 mcr.microsoft.com/azure-sql-edge
62-
docker run --rm -d -p 2181:2181 -p 443:2008 -p 2008:2008 -p 2009:2009 \
63-
--env ADVERTISED_LISTENERS=PLAINTEXT://localhost:443,INTERNAL://localhost:2009 \
64-
--env LISTENERS=PLAINTEXT://0.0.0.0:2008,INTERNAL://0.0.0.0:2009 \
65-
--env SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT \
66-
--env INTER_BROKER=INTERNAL \
67-
--env KAFKA_CREATE_TOPICS="test-topic,test:36:1,krisgeus:12:1:compact" \
68-
--name gofr-kafka \
69-
krisgeus/docker-kafka
70-
71-
docker run --name gofr-yugabyte -p 2011:9042 -d yugabytedb/yugabyte:2.14.5.0-b18 bin/yugabyted start --daemon=false
72-
docker run -d --name gofr-elasticsearch -p 2012:9200 -p 2013:9300 -e "discovery.type=single-node" elasticsearch:6.8.6
73-
docker run -d --name gofr-dynamodb -p 2021:8000 amazon/dynamodb-local:1.22.0
74-
docker run -d --name=gofr-cockroachdb -p 26257:26257 cockroachdb/cockroach:v21.2.4 start-single-node --insecure
75-
docker run --name=gcloud-emulator -d -p 8086:8086 gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators gcloud beta emulators pubsub start --project=test123 \
76-
--host-port=0.0.0.0:8086
59+
docker run --name zookeeper -e ZOOKEEPER_CLIENT_PORT=2181 -e ZOOKEEPER_TICK_TIME=2000 confluentinc/cp-zookeeper:7.0.1
60+
docker run --name broker -p 9092:9092 --link zookeeper -e KAFKA_BROKER_ID=1 \
61+
-e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \
62+
-e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_INTERNAL:PLAINTEXT \
63+
-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092,PLAINTEXT_INTERNAL://broker:29092 \
64+
-e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \
65+
-e KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=1 \
66+
-e KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=1 \
67+
confluentinc/cp-kafka:7.0.1
7768

7869
Please note that the recommended local port for the services are different than the actual ports. This is done to avoid conflict with the local installation on developer machines. This method also allows a developer to work on multiple projects which uses the same services but bound on different ports. One can choose to change the port for these services. Just remember to add the same in configs/.local.env, if you decide to do that.
7970
```

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ If you want to say thank you and/or support the active development of GoFr:
3939

4040
1. Add a [GitHub Star](https://github.com/gofr-dev/gofr/stargazers) to the project.
4141
2. Write a review or tutorial on [Medium](https://medium.com/), [Dev.to](https://dev.to/) or personal blog.
42-
3. Visit [CONTRIBUTING](CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
42+
3. Visit [CONTRIBUTING](CONTRIBUTING.md) for details on submitting patches and the contribution workflow. After your PR is merged to the repo, drop us a line with your address, phone number and tshirt size, we will send you a free Gofr T-Shirt as a token of appreciation.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Dealing with SQL
2+
3+
GoFr simplifies the process of connecting to SQL databases where one needs to add respective configs in .env,
4+
which allows to connect to different SQL dialects(MYSQL, PostgreSQL) without going into complexity of configuring connections.
5+
6+
With GoFr, connecting to different SQL databases is as straightforward as setting the DB_DIALECT environment variable to the respective dialect.
7+
For instance, to connect with PostgreSQL, set `DB_DIALECT` to `postgres`. Similarly, To connect with MySQL, simply set `DB_DIALECT` to `mysql`.
8+
9+
## Usage
10+
Add the following configs in .env file.
11+
12+
```bash
13+
DB_HOST=localhost
14+
DB_USER=root
15+
DB_PASSWORD=root123
16+
DB_NAME=test_db
17+
DB_PORT=3306
18+
19+
DB_DIALECT=postgres
20+
```
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Injecting Database Drivers
2+
Keeping in mind the size of the framework in the final build, it felt counter-productive to keep all the database drivers within
3+
the framewrork itself. Keeping only the most used MySQL and Redis within the framework, users can now inject databases
4+
in the server that staisfies the base interface defined by GoFr. This helps in reducing the build size and in turn build time
5+
as unnecessary database drivers are not being compiled and added to the build.
6+
7+
> We are planning to provide custom drivers for most common databases, and is in the pipeline for upcoming releases!
8+
9+
## Mongo DB
10+
Gofr supports injecting Mongo DB that supports the following interface. Any driver that implements the interface can be added
11+
using `app.UseMongo()` method, and user's can use MonogDB across application with `gofr.Context`.
12+
```go
13+
type Mongo interface {
14+
Find(ctx context.Context, collection string, filter interface{}, results interface{}) error
15+
16+
FindOne(ctx context.Context, collection string, filter interface{}, result interface{}) error
17+
18+
InsertOne(ctx context.Context, collection string, document interface{}) (interface{}, error)
19+
20+
InsertMany(ctx context.Context, collection string, documents []interface{}) ([]interface{}, error)
21+
22+
DeleteOne(ctx context.Context, collection string, filter interface{}) (int64, error)
23+
24+
DeleteMany(ctx context.Context, collection string, filter interface{}) (int64, error)
25+
26+
UpdateByID(ctx context.Context, collection string, id interface{}, update interface{}) (int64, error)
27+
28+
UpdateOne(ctx context.Context, collection string, filter interface{}, update interface{}) error
29+
30+
UpdateMany(ctx context.Context, collection string, filter interface{}, update interface{}) (int64, error)
31+
32+
CountDocuments(ctx context.Context, collection string, filter interface{}) (int64, error)
33+
34+
Drop(ctx context.Context, collection string) error
35+
}
36+
```
37+
38+
User's can easily inject a driver that supports this interface, this provides usability without
39+
compromising the extensability to use multiple databases.
40+
### Example
41+
```go
42+
package main
43+
44+
import (
45+
mongo "github.com/vipul-rawat/gofr-mongo"
46+
"go.mongodb.org/mongo-driver/bson"
47+
48+
"gofr.dev/pkg/gofr"
49+
)
50+
51+
type Person struct {
52+
Name string `bson:"name" json:"name"`
53+
Age int `bson:"age" json:"age"`
54+
City string `bson:"city" json:"city"`
55+
}
56+
57+
func main() {
58+
app := gofr.New()
59+
60+
// using the mongo driver from `vipul-rawat/gofr-mongo`
61+
db := mongo.New(app.Config, app.Logger(), app.Metrics())
62+
63+
// inject the mongo into gofr to use mongoDB across the application
64+
// using gofr context
65+
app.UseMongo(db)
66+
67+
app.POST("/mongo", Insert)
68+
app.GET("/mongo", Get)
69+
70+
app.Run()
71+
}
72+
73+
func Insert(ctx *gofr.Context) (interface{}, error) {
74+
var p Person
75+
err := ctx.Bind(&p)
76+
if err != nil {
77+
return nil, err
78+
}
79+
80+
res, err := ctx.Mongo.InsertOne(ctx, "collection", p)
81+
if err != nil {
82+
return nil, err
83+
}
84+
85+
return res, nil
86+
}
87+
88+
func Get(ctx *gofr.Context) (interface{}, error) {
89+
var result Person
90+
91+
p := ctx.Param("name")
92+
93+
err := ctx.Mongo.FindOne(ctx, "collection", bson.D{{"name", p}} /* valid filter */, &result)
94+
if err != nil {
95+
return nil, err
96+
}
97+
98+
return result, nil
99+
}
100+
```

docs/advanced-guide/monitoring-service-health/page.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ To override this endpoint, pass the following option while registering HTTP Serv
2828
}
2929
```
3030

31-
### 2. Health-Check - /.well-known/health-check
31+
### 2. Health-Check - /.well-known/health
3232

3333
It is an endpoint which returns whether the service is UP or DOWN along with stats, host, status about the dependent datasources and services.
3434

docs/advanced-guide/publishing-custom-metrics/page.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func main() {
9999

100100
// transaction logic
101101

102-
tranTime := time.Now().Sub(transactionStartTime).Microseconds()
102+
tranTime := time.Now().Sub(transactionStartTime).Milliseconds()
103103

104104
ctx.Metrics().RecordHistogram(ctx, "transaction_time", float64(tranTime))
105105

docs/navigation.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const navigation = [
77
{ title: 'Connecting Redis', href: '/docs/quick-start/connecting-redis' },
88
{ title: 'Connecting MySQL', href: '/docs/quick-start/connecting-mysql' },
99
{ title: 'Observability', href: '/docs/quick-start/observability' },
10+
{ title: 'Adding REST Handlers', href: '/docs/quick-start/add-rest-handler' },
1011
],
1112
},
1213
{
@@ -21,7 +22,9 @@ export const navigation = [
2122
{ title: 'Monitoring Service Health', href: '/docs/advanced-guide/monitoring-service-health' },
2223
{ title: 'Handling Data Migrations', href: '/docs/advanced-guide/handling-data-migrations' },
2324
{ title: 'Writing gRPC Server', href: '/docs/advanced-guide/grpc' },
24-
{ title: 'Using Pub/Sub', href: '/docs/advanced-guide/using-publisher-subscriber' }
25+
{ title: 'Using Pub/Sub', href: '/docs/advanced-guide/using-publisher-subscriber' },
26+
{ title: 'Injecting Databases', href: '/docs/advanced-guide/injecting-databases-drivers' },
27+
{ title: 'Dealing with Datasources', href: '/docs/advanced-guide/dealing-with-datasources' },
2528
// { title: 'Dealing with Remote Files', href: '/docs/advanced-guide/remote-files' },
2629
// { title: 'Supporting OAuth', href: '/docs/advanced-guide/oauth' },
2730
// { title: 'Creating a Static File Server', href: '/docs/advanced-guide/static-file-server' },
@@ -44,4 +47,4 @@ export const navigation = [
4447
// { title: 'Swaggger', href: '/docs/references/swagger' },
4548
],
4649
},
47-
]
50+
]
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Add REST Handlers
2+
3+
GoFr simplifies the process of implementing CRUD (Create, Read, Update, Delete) operations by enabling the automatic generation of handlers directly from Go structs.
4+
This feature eliminates the need for writing repetitive boilerplate code, allowing developers to focus on application logic.
5+
6+
## Default Behaviour
7+
8+
If the custom handlers ain't implemented on the struct, GoFr provides default handlers for each CRUD operation. These handlers handle basic database interactions:
9+
10+
- **Create**: `/entity` Inserts a new record based on data provided in a JSON request body.
11+
- **Read**:
12+
- **GET**: `/entity` Retrieves all entities of the type specified by the struct.
13+
- **GET**: `/entity/{id}` Retrieves a specific entity identified by the {id} path parameter.
14+
- **Update**: `/entity/{id}` Updates an existing record identified by the {id} path parameter, based on data provided in a JSON request body.
15+
- **Delete** `/entity/{id}` Deletes an existing record identified by the {id} path parameter.
16+
17+
**NOTE**: The registered routes will have the same name as the given struct.
18+
19+
## Overriding Default Handlers
20+
21+
While the default handlers provide basic functionality, user might want to customize their behavior for specific use cases.
22+
The AddRESTHandlers feature allows user to override these handlers by implementing methods within the struct itself.
23+
24+
## Benefits of Adding REST Handlers of GoFr
25+
26+
1. Reduced Boilerplate Code: Eliminate repetitive code for CRUD operations, freeing user to focus on core application logic.
27+
2. Consistency: Ensures consistency in CRUD operations across different entities by using a standardized approach.
28+
3. Flexibility: Allows developers to customize CRUD behavior as per application requirements, providing flexibility and extensibility.
29+
30+
## Example
31+
32+
```go
33+
package main
34+
35+
import (
36+
"gofr.dev/examples/using-crud-from-struct/migrations"
37+
"gofr.dev/pkg/gofr"
38+
)
39+
40+
type user struct {
41+
Id int `json:"id"`
42+
Name string `json:"name"`
43+
Age int `json:"age"`
44+
IsEmployed bool `json:"isEmployed"`
45+
}
46+
47+
// GetAll : User can overwrite the specific handlers by implementing them like this
48+
func (u *user) GetAll(c *gofr.Context) (interface{}, error) {
49+
return "user GetAll called", nil
50+
}
51+
52+
func main() {
53+
// Create a new application
54+
a := gofr.New()
55+
56+
// Add migrations to run
57+
a.Migrate(migrations.All())
58+
59+
// AddRESTHandlers creates CRUD handles for the given entity
60+
err := a.AddRESTHandlers(&user{})
61+
if err != nil {
62+
return
63+
}
64+
65+
// Run the application
66+
a.Run()
67+
}
68+
```
69+
70+
In this example, we define a user struct representing a database entity. The GetAll method in the provided code demonstrates how to override the default behavior for retrieving all entities.
71+
This method can be used to implement custom logic for filtering, sorting, or retrieving additional data along with the entities.
72+
73+
74+
> Few Points to consider:
75+
> 1. Struct Naming Convention: By default, GoFr assumes the struct name matches the database table name for querying data.
76+
> 2. Primary Key: The first field of the struct is typically used as the primary key for data operations. However, user can customize this behavior using GoFr's features.

0 commit comments

Comments
 (0)