Giter VIP home page Giter VIP logo

gofr's Introduction

GoFr

logo


GoFr is an opinionated microservice development framework. Listed in CNCF Landscape.

Visit https://gofr.dev for more details and documentation.

๐ŸŽฏ Goal

Even though generic applications can be written using GoFr, our main focus is to simplify the development of microservices. We will focus ourselves towards deployment in Kubernetes and aspire to provide out-of-the-box observability.

๐Ÿ’ก Advantages/Features

  1. Simple API syntax
  2. REST Standards by default
  3. Configuration management
  4. Inbuilt Middlewares
  5. gRPC support
  6. HTTP service with support for Circuit Breaker and Health Check

๐Ÿ‘ Contribute

If you want to say thank you and/or support the active development of GoFr:

  1. Add a GitHub Star to the project.
  2. Write a review or tutorial on Medium, Dev.to or personal blog.
  3. Visit CONTRIBUTING for details on submitting patches and the contribution workflow. After your PR is merged to the repo, fill the Google Form, and we will send you a GoFr T-Shirt and Stickers as a token of appreciation.

gofr's People

Contributors

00harald avatar achimgrolimund avatar aditya028 avatar aryanmehrotra avatar bhavya-arora-zs avatar ccoveille avatar chauhan17nitin avatar dependabot[bot] avatar guykh avatar illenko avatar ivangael avatar kailashchoudhary11 avatar kedarisettisreevamsi avatar lloistborn avatar ohjuhun avatar piyushsingh-zs avatar rokerzfirst101 avatar sianao avatar srijan-27 avatar ssshekhu53 avatar surajitpore0 avatar suyeshbadge avatar umang01-hash avatar vikash avatar vipul-rawat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gofr's Issues

Unexpected errors from handlers does not get logged including DB errors

If any handler returns an error which results into 500 error from handler, the error is not getting logged at any level.

For example, if handler has following as return statement:
return h.store.Create(ctx, cust)

and the Create function has an error returned, it is expected to get it logged.

App logger's LOG_LEVEL resets to DEBUG when NewMockLogger is used

Looks like a global variable is used to set the log levels, and calling NewMockLogger resets this global variable to DEBUG.

Additional Questions

  • Considering the name NewMockLogger, is it only supposed to be used within tests? If so, can we add some godocs regarding this since accidental usage affects the app's logging.
  • Should this global variable be shared with the MockLogger?

Replicate the Issue

project/
โ”œโ”€โ”€ configs/
โ”‚   โ””โ”€โ”€ .env
โ”œโ”€โ”€ main.go
โ””โ”€โ”€ go.mod

.env

LOG_LEVEL=WARN

main.go

package main

import (
	"fmt"
	"io"

	"gofr.dev/pkg/gofr"
	"gofr.dev/pkg/log"
)

func main() {
	app := gofr.New()

	fmt.Println("LOG_LEVEL:", app.Config.Get("LOG_LEVEL"))

	log.NewMockLogger(io.Discard)

	app.Logger.Debug("DEBUG log")
	app.Logger.Info("INFO log")
	app.Logger.Warn("WARN log")
	app.Logger.Error("ERROR log")
	app.Logger.Fatal("FATAL log")

	app.Start()
}

output

LOG_LEVEL: WARN
DEBU [13:09:58]  DEBUG log
                 (Memory: 6557824 GoRoutines: 2) 
INFO [13:09:58]  INFO log
                 (Memory: 6559168 GoRoutines: 2) 
WARN [13:09:58]  WARN log
                 (Memory: 6560512 GoRoutines: 2) 
ERRO [13:09:58]  ERROR log
     StackTrace: goroutine 1 [running]:
                       .       .        .
                 (Memory: 6563576 GoRoutines: 2) 
FATA [13:09:58]  FATAL log
     StackTrace: goroutine 1 [running]:
                       .       .        .
                 (Memory: 6568744 GoRoutines: 2) 
exit status 1

c.Bind is not working when the request is made via html form but works from postman

Here is the HTML form

<form method="POST" action="/login">
    <input type = "text" name = "username" placeholder="username"/>
    <input type  = "password" name="password" placeholder="password"/>
    <input type = "submit" value="Login"/>
</form>

The header value of content type is application/x-www-form-urlencoded

//Backend code
package models
type Login struct {
	Username string `json:"username"`
	Password string `json:"password"`
}
package handlers
func LogiReq(c *gofr.Context) (interface{}, error) {
	c.Logger.Info("Login request ")
	var login models.Login
	err := c.Bind(&login)
	if err != nil {
		c.Logger.Errorf("Error in binding request body %w ", err)
	}
	c.Logger.Info("Login request for username ", login.Username)
	return login.Username, nil
}

The above code throws error on c.Bind.
*ERRO [14:06:48] Error in binding request body %!w(json.SyntaxError=&{invalid character 'u' looking for beginning of value 1}) StackTrace: goroutine 82 [running]:

However, it works fine when the request is sent from PostMan

Log Stacking

Background

In case of production systems, log level is often set to ERROR and hence any messages logged at lower levels are not printed. However, in case of an error encountered, such logs are crucial. Application teams most end up changing the log level to lower values in the hope of encountering the error again, with the detailed logs available this time.

Challenges with current process (lowering the log level)

  • High turn-around time for the application team to isolate the issue
  • Increased log volumes causing spike in the cost of processing & storing logs. May also impact the performance of the application as well due to excessive logging.

Requirement

In case of an error level log in a request, all messages logged in the request till that point (within the context) should also get printed so that the application team does not need to change the log level to get the detailed logs.

Implementation Proposed

Framework to maintain the messaged, logged at lower levels, in memory and print them out whenever a message is logged at ERROR or higher level. Stack trace being printed in the ERROR log may also be removed given that it does not have much utility for scenarios where messages are logged at ERROR level.

Refactor testcases in framework

As of now, there are two packages used in test cases in the framework i.e. testify and reflect. We should remove reflect and use the testify package in all the test cases(apart from mock_interfaces).

Add code coverage as PR comment

Currently pipeline is failing for the forks trying to create a PR as the upload coverage step fails to upload the code coverage!
The current implementation needs to be changed, and for PRs add code coverage as a comment to the PR and upload the code coverage to code-climate only when there is an update in the developement branch.

Lack of Support for Grouping of Routes

Summary:

The current version of gofr lacks support for grouping routes, which is a fundamental feature for organizing and managing complex web applications efficiently.

Description:

In many modern web applications, the number of routes can grow significantly, leading to a potential lack of organization and readability in the codebase. Grouping routes provides a clean and structured way to manage related routes under a common namespace, enhancing code maintainability and developer experience.

Expected Behavior:

I expect gofr to incorporate a feature that allows developers to group routes, similar to how other popular frameworks/libraries (e.g., gin, echo) provide this functionality. This feature should permit developers to organize routes logically, making the codebase more modular and easier to navigate.

Use Case:

Consider the scenario where an application has multiple API endpoints related to user authentication, each requiring different levels of access. With route grouping, developers could define a "auth" group and nest routes for login, registration, and user profile under this namespace. This would result in cleaner and more maintainable code, as well as improved readability.

Additional Questions:

  1. Are there any existing workarounds or alternative solutions?
  2. How might the proposed feature align with the overall philosophy and architecture of gofr?

Divide Tests in Pipeline

Divide examples, cmd and pkg tests such that they run parallelly.
It will reduce the total time to run the tests as well as if some test fails, we can run that part separately.

Fix l Disabled TLS certificate check

Tracking issue for:

func processSASLConfigs(s SASLConfig, conf *sarama.Config) {
	if s.User != "" && s.Password != "" {
		conf.Net.SASL.User = s.User
		conf.Net.SASL.Password = s.Password
		conf.Net.SASL.Handshake = true
		conf.Net.SASL.Enable = true
		conf.Net.TLS.Enable = true
		conf.Net.TLS.Config = &tls.Config{
			InsecureSkipVerify: true, //nolint:gosec // TLS InsecureSkipVerify set true.
		}

Handle Panic when subscriptionDetails is passed nil in google PubSub

  • I was trying to create publisher but got panic, if didn't passed subscriptionDetails

How to regenerate the panic

disputeStatusPublisher, pubErr := googlePubSub.New(&googlePubSub.Config{
			TopicName:           disputeStatusPublisherTopicName,
			ProjectID:           projectID,
			TimeoutDuration:     30,
			Subscription:        nil,
			Topic:               nil,
			SubscriptionDetails: nil,
		}, logger)`

currently it is giving panic due to

g.config.Subscription = g.client.Subscription(g.config.SubscriptionDetails.Name)

Expected :-

It should give an error stating subscriptionDetails is necessary

Fix CMD Panics

  1. if any argument after valid command/route is -
    os.Args = []string{"", "log", "-param=value", "-b", "-"}

  2. If command/route ends with ( or ) - if both are present it works fine - it is because of regex expression

Has to be fixed in the following files

  1. gofr/pkg/gofr/cmd/request.go
  2. gofr/pkg/gofr/cmd.go

AVRO should be injected inside Supported Pub/Sub

Currently, Kafka is injected inside AVRO i.e it is tightly coupled.
Rather it should be implemented such that AVRO can be used with any of the pub/sub supported like google pubsub, eventbridge, etc.

Merge docs repo in this repo

Documentation is being managed in a separate repo. So, people who want to contribute have to go to different places. Similarly, when something changes in the codebase, we need to ensure that documents are changing accordingly as part of same PR to avoid documentation conflicts. This will also help people in referring the docs directly from the codebase.

Intermittent Test Failure: Fix Move_Test in ftp

Description

Test_move in ftp_test.go is failing intermittently for the error case and always getting connection related errors.
Have a fix for it i.e try to close connections so that this error can be avoided.

How to reproduce

  • Run Test_move function recursively using below command
go test -run=Test_move -count=100

Expectations

&textproto.Error{Code:550, Msg:"RNFR command failed."}

Actual result

&textproto.Error{Code:421, Msg:"There are too many connections from your internet address."}

Environment

go version: go1.21 darwin_arm64
go version: v1.0.0
operating system: Mac OS

Fix Uncontrolled data used in path expression Security Vulnerability

Remove ZopSmart specific things

As the framework originated at ZopSmart, some places we have some specific things like zopsmart-tenant etc. We should be reviewing and removing those things.

GoFr: error while reading config

GoFr v1.0.0 everything is working fine.

but while using GoFr v1.0.3 we are getting some errors like

WARN [11:28:26]  Failed to load config from file: ./configs/.env, Err: unexpected character "-" in variable name near "Access-Control-Allow-Headers=\"g-recaptcha-response,Content-Type\"\n\n#Auth Configs\nAUTH_URL=\nAUTH_REALM_ID=\nAUTH_LOGIN_ENDPOINT=/login\nAUTH_REFRESH_ENDPOINT=/refresh\nAUTH_JWKS_ENDPOINT=\n\n#ROS\nLOG_SERVICE_URL=https://remote-config-func.observability-prod.gcp.zopsmart.com/\nLOG_SERVICE_CLUSTER=\nLOG_SERVICE_USER_GROUP=\nLOG_SERVICE_NAMESPACE=\n\nREMOTE_CONFIG_URL=https://remote-config-func.observability-prod.gcp.zopsmart.com/\nREMOTE_CLUSTER=\nREMOTE_USER_GROUP=\nREMOTE_NAMESPACE="

It does not support the - separate variable in the env variables.

Please fix this problem.

Pipeline Failing

One of the example or package is failing when package and example tests are running together.
Running either of them after one passes is passed succefuly.
One Proposed solution is to make them run after one another or merge into one.

Fix code scanning Security Issues

Increase Test Coverage

Currently , we are having coverage of 92%

Add tests to increase the overall coverage of gofr

pub/sub error in new verision of gofr

I was running the example/sample-API of gofr repo.While i run the main file i got the error that says

"# gofr.dev/pkg/datastore/pubsub/eventhub
....\go\pkg\mod\[email protected]\pkg\datastore\pubsub\eventhub\eventhub.go:70:60: cannot use tokenProvider (variable of type "github.com/Azure/azure-amqp-common-go/v3/sas".TokenProvider) as "github.com/Azure/azure-amqp-common-go/v4/auth".TokenProvider value in argument to eventhub.NewHub: "github.com/Azure/azure-amqp-common-go/v3/sas".TokenProvider does not implement "github.com/Azure/azure-amqp-common-go/v4/auth".TokenProvider (wrong type for method GetToken)
have GetToken(string) (
"github.com/Azure/azure-amqp-common-go/v3/auth".Token, error)
want GetToken(string) (
"github.com/Azure/azure-amqp-common-go/v4/auth".Token, error)
....\go\pkg\mod\[email protected]\pkg\datastore\pubsub\eventhub\eventhub.go:83:59: cannot use jwtProvider (variable of type "github.com/Azure/azure-amqp-common-go/v3/aad".TokenProvider) as "github.com/Azure/azure-amqp-common-go/v4/auth".TokenProvider value in argument to eventhub.NewHub: "github.com/Azure/azure-amqp-common-go/v3/aad".TokenProvider does not implement "github.com/Azure/azure-amqp-common-go/v4/auth".TokenProvider (wrong type for method GetToken)
have GetToken(string) (
"github.com/Azure/azure-amqp-common-go/v3/auth".Token, error)
want GetToken(string) (
"github.com/Azure/azure-amqp-common-go/v4/auth".Token, error)"

Although i downgraded the version after which this error vanished.I even tried go mod tidy but still i got this error.After downgrading i got this error

"# gofr.dev/pkg/datastore
....\go\pkg\mod\[email protected]\pkg\datastore\db.go:361:45: cannot use semconv.DBSystemPostgreSQL.Value.AsString() (value of type string) as otelsql.Option value in argument to otelsql.Register: string does not implement otelsql.Option (missing method Apply)
....\go\pkg\mod\[email protected]\pkg\datastore\db.go:363:45: cannot use dialect (variable of type string) as otelsql.Option value in argument to otelsql.Register: string does not implement otelsql.Option (missing method Apply)"

I have uploaded whole codebase that i wrote at https://github.com/saksham5701/mini-pro-gofr-zopsmart

CORS: irrelevant headers are indiscriminately set in the preflight/actual responses

The CORS middleware sets each ((if its value is non-empty) of the following headers in both preflight responses and actual responses:

Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Credentials
Access-Control-Expose-Headers
Access-Control-Max-Age

However, the only relevant headers for preflight responses are the following:

Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Credentials
Access-Control-Max-Age

And the only relevant headers for actual responses are the following:

Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Expose-Headers

Middleware should avoid setting irrelevant headers because doing so has a cost, both in terms of transport and in terms of heap allocations on the server.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.