{"id":31917272,"url":"https://github.com/linhbkhn95/grpc-scaffolding","last_synced_at":"2026-05-18T10:32:52.140Z","repository":{"id":61347407,"uuid":"550594627","full_name":"linhbkhn95/grpc-scaffolding","owner":"linhbkhn95","description":"grpc-scaffolding aims to scaffold grpc project quickly by generating code via the proto definition and go template.","archived":false,"fork":false,"pushed_at":"2022-10-25T07:19:05.000Z","size":72,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-21T10:58:52.663Z","etag":null,"topics":["framework","go","grpc","hacktoberfest","hacktoberfest2022","protobuf","scaffolding","template"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linhbkhn95.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-10-13T02:43:58.000Z","updated_at":"2024-06-21T10:58:52.668Z","dependencies_parsed_at":"2023-01-20T11:36:05.902Z","dependency_job_id":null,"html_url":"https://github.com/linhbkhn95/grpc-scaffolding","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/linhbkhn95/grpc-scaffolding","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhbkhn95%2Fgrpc-scaffolding","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhbkhn95%2Fgrpc-scaffolding/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhbkhn95%2Fgrpc-scaffolding/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhbkhn95%2Fgrpc-scaffolding/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linhbkhn95","download_url":"https://codeload.github.com/linhbkhn95/grpc-scaffolding/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linhbkhn95%2Fgrpc-scaffolding/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279016944,"owners_count":26085907,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framework","go","grpc","hacktoberfest","hacktoberfest2022","protobuf","scaffolding","template"],"created_at":"2025-10-13T20:26:48.590Z","updated_at":"2025-10-13T20:27:03.786Z","avatar_url":"https://github.com/linhbkhn95.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# grpc-scaffolding\ngrpc-scaffolding aims to scaffold grpc project quickly by generating code via the proto definition and go template.\n\nThe following is Go project layout scaffold generated:\n\n```\n├── Dockerfile\n├── Makefile\n├── .gitignore\n├── .env.example\n├── README.md\n├── cmd\n│   └── main.go\n├── config\n│   ├── config.go\n│ \n├── internal/ should put business logic here.\n├── pkg/\n└── server\n│   ├── handler\n│   │     ├── health.go\n│   │     ...\n│   ├── grpc\n│   │     ├── server.go\n│   ├── server.go\n```\nif you define service proto at repo `rpc-proto` like:\n\n```proto\n...\n// HealthService ...\nservice HealthService {\n  // Ready ...\n  rpc Ready (ReadyRequest) returns (ReadyResponse) {\n    option (google.api.http) = {\n      post: \"/api/v1/ready\"\n      body: \"*\"\n    };\n  }\n}\n\n// ReadyRequest ...\nmessage ReadyRequest{\n}\n\n// ReadyResponse ...\nmessage ReadyResponse {\n}\n\n...\n// ExampleService ...\nservice ExampleService {\n  // Hello ...\n  rpc Hello (HelloRequest) returns (HelloResponse) {\n    option (google.api.http) = {\n      post: \"/api/v1/hello\"\n      body: \"*\"\n    };\n  }\n}\n\n// HelloRequest defines input to hello.\nmessage HelloRequest{\n  string msg = 1 [(validate.rules).string.min_len = 1];\n}\n\n// HelloResponse ...\nmessage HelloResponse {\n  string msg = 1;\n}\n\n```\nproject generated will has files like:\n\n`project-name/server/grpc/server.go`\n\n```\n\n// Code generated by go generate; DO NOT EDIT.\n// This file was generated by @generated\n// source: codegen/grpcserver/tmpl/server.go.tmpl\n\npackage server\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\n\thttp \"net/http\"\n\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/runtime\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\tpromhttp \"github.com/prometheus/client_golang/prometheus/promhttp\"\n\n\texamplev1 \"github.com/linhbkhn95/grpc-service/go/example/v1\"\n\thealthv1 \"github.com/linhbkhn95/grpc-service/go/health/v1\"\n\tgrpc \"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\t\"google.golang.org/protobuf/encoding/protojson\"\n)\n\ntype (\n\t// Server is server struct which contains both grpc and http server.\n\tServer struct {\n\t\tgRPC                 *grpc.Server\n\t\tmux                  *runtime.ServeMux\n\t\tcfg                  Config\n\t\tisRunningDevelopment bool\n\t}\n\n\t// Config hold http/grpc server config\n\tConfig struct {\n\t\tGRPC ServerListen `yaml:\"grpc\" mapstructure:\"grpc\"`\n\t\tHTTP ServerListen `yaml:\"http\" mapstructure:\"http\"`\n\t}\n\n\t// ServerListen config for host/port socket listener\n\t// nolint:revive\n\tServerListen struct {\n\t\tHost string `yaml:\"host\" mapstructure:\"host\"`\n\t\tPort int    `yaml:\"port\" mapstructure:\"port\"`\n\t}\n)\n\n// DefaultConfig return a default server config\nfunc DefaultConfig() Config {\n\treturn NewConfig(10443, 10080)\n}\n\n// NewConfig return a optional config with grpc port and http port.\nfunc NewConfig(grpcPort, httpPort int) Config {\n\treturn Config{\n\t\tGRPC: ServerListen{\n\t\t\tHost: \"0.0.0.0\",\n\t\t\tPort: grpcPort,\n\t\t},\n\n\t\tHTTP: ServerListen{\n\t\t\tHost: \"0.0.0.0\",\n\t\t\tPort: httpPort,\n\t\t},\n\t}\n}\n\n// String return socket listen DSN\nfunc (l ServerListen) String() string {\n\treturn fmt.Sprintf(\"%s:%d\", l.Host, l.Port)\n}\n\nfunc NewServer(cfg Config, isRunningDevelopment bool, opt ...grpc.ServerOption) *Server {\n\treturn \u0026Server{\n\t\tgRPC: grpc.NewServer(opt...),\n\t\tmux: runtime.NewServeMux(\n\t\t\truntime.WithMarshalerOption(runtime.MIMEWildcard,\n\t\t\t\t\u0026runtime.JSONPb{\n\t\t\t\t\tMarshalOptions: protojson.MarshalOptions{\n\t\t\t\t\t\tUseProtoNames:   false,\n\t\t\t\t\t\tUseEnumNumbers:  false,\n\t\t\t\t\t\tEmitUnpopulated: true,\n\t\t\t\t\t},\n\t\t\t\t\tUnmarshalOptions: protojson.UnmarshalOptions{\n\t\t\t\t\t\tDiscardUnknown: true,\n\t\t\t\t\t},\n\t\t\t\t})),\n\t\tcfg:                  cfg,\n\t\tisRunningDevelopment: isRunningDevelopment,\n\t}\n}\nfunc (s *Server) Register(grpcServer ...interface{}) error {\n\tfor _, srv := range grpcServer {\n\t\tswitch _srv := srv.(type) {\n\n\t\tcase healthv1.HealthServiceServer:\n\t\t\thealthv1.RegisterHealthServiceServer(s.gRPC, _srv)\n\t\t\tif err := healthv1.RegisterHealthServiceHandlerFromEndpoint(context.Background(), s.mux, s.cfg.GRPC.String(), []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\tcase examplev1.ExampleServiceServer:\n\t\t\texamplev1.RegisterExampleServiceServer(s.gRPC, _srv)\n\t\t\tif err := examplev1.RegisterExampleServiceHandlerFromEndpoint(context.Background(), s.mux, s.cfg.GRPC.String(), []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"Unknown GRPC Service to register %#v\", srv)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Serve server listen for HTTP and GRPC\nfunc (s *Server) Serve() error {\n\tstop := make(chan os.Signal, 1)\n\terrch := make(chan error)\n\tsignal.Notify(stop, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)\n\n\thttpMux := http.NewServeMux()\n\n\thttpMux.Handle(\"/metrics\", promhttp.Handler())\n\n\thttpMux.Handle(\"/\", s.mux)\n\thttpServer := http.Server{\n\t\tAddr:    s.cfg.HTTP.String(),\n\t\tHandler: httpMux,\n\t}\n\tgo func() {\n\t\tif err := httpServer.ListenAndServe(); err != nil {\n\t\t\terrch \u003c- err\n\t\t}\n\t}()\n\n\tgo func() {\n\t\tlistener, err := net.Listen(\"tcp\", s.cfg.GRPC.String())\n\t\tif err != nil {\n\t\t\terrch \u003c- err\n\t\t\treturn\n\t\t}\n\t\tif err := s.gRPC.Serve(listener); err != nil {\n\t\t\terrch \u003c- err\n\t\t}\n\t}()\n\tfor {\n\t\tselect {\n\t\tcase \u003c-stop:\n\t\t\tctx, cancelFn := context.WithTimeout(context.Background(), 30*time.Second)\n\t\t\tdefer cancelFn()\n\t\t\ts.gRPC.GracefulStop()\n\n\t\t\tif err := httpServer.Shutdown(ctx); err != nil {\n\t\t\t\tfmt.Println(\"failed to stop server: %w\", err)\n\t\t\t}\n\n\t\t\tif !s.isRunningDevelopment {\n\t\t\t\tfmt.Println(\"Shutting down. Wait for 15 seconds\")\n\t\t\t\ttime.Sleep(15 * time.Second)\n\t\t\t}\n\t\t\treturn nil\n\t\tcase err := \u003c-errch:\n\t\t\treturn err\n\t\t}\n\t}\n}\n\n```\n`project-name/server/handler/health.go`\n\n```\n\npackage handler\n\nimport (\n\t\"context\"\n\n\thealthv1 \"github.com/linhbkhn95/grpc-service/go/health/v1\"\n)\n\ntype HealthServer struct {\n\thealthv1.UnimplementedHealthServiceServer\n}\n\nfunc NewHealthServer() healthv1.HealthServiceServer {\n\treturn \u0026HealthServer{}\n}\n\n//TODO: implement methods of this service.\n\n// Ready ...\nfunc (s HealthServer) Ready(ctx context.Context, req *healthv1.ReadyRequest) (*healthv1.ReadyResponse, error) {\n\treturn \u0026healthv1.ReadyResponse{}, nil\n}\n\n```\n\n`project-name/server/handler/example.go`\n\n```\n\npackage handler\n\nimport (\n\t\"context\"\n\n\texamplev1 \"github.com/linhbkhn95/grpc-service/go/example/v1\"\n)\n\ntype ExampleServer struct {\n\texamplev1.UnimplementedExampleServiceServer\n}\n\nfunc NewExampleServer() examplev1.ExampleServiceServer {\n\treturn \u0026ExampleServer{}\n}\n\n//TODO: implement methods of this service.\n\n// SayHello will send hello term to server.\nfunc (s ExampleServer) SayHello(ctx context.Context, req *examplev1.SayHelloRequest) (*examplev1.SayHelloResponse, error) {\n\treturn \u0026examplev1.SayHelloResponse{}, nil\n}\n\n// SayGoodbye will send goodbye term to server.\nfunc (s ExampleServer) SayGoodbye(ctx context.Context, req *examplev1.SayGoodbyeRequest) (*examplev1.SayGoodbyeResponse, error) {\n\treturn \u0026examplev1.SayGoodbyeResponse{}, nil\n}\n\n```\n## Features\n- Easy generate project from proto definition\n- Provide layout standard and `rpc server` instance for implementation. Separate layer `transport` and `service`\n\n\n\n\n\n## Modules\n```\n  - layout\n\n  - grpc_server\n```\n\n## Usage\n  1. install: `go get github.com/linhbkhn95/grpc-scaffolding` or `go install  github.com/linhbkhn95/grpc-scaffolding@latest`\n  if your terminal throw error like\n  ```\n  go: downloading github.com/linhbkhn95/grpc-scaffolding v0.0.0-20220728042906-33c17ac9cdfd\ngo: github.com/linhbkhn95/grpc-scaffolding@latest: github.com/linhbkhn95/grpc-scaffolding@v0.0.0-20220728042906-33c17ac9cdfd: verifying module: github.com/linhbkhn95/grpc-scaffolding@v0.0.0-20220728042906-33c17ac9cdfd: reading https://sum.golang.org/lookup/github.com/!kyber!network/rpc-framework@v0.0.0-20220728042906-33c17ac9cdfd: 410 Gone\n\tserver response:\n\tnot found: github.com/linhbkhn95/grpc-scaffolding@v0.0.0-20220728042906-33c17ac9cdfd: invalid version: git ls-remote -q origin in /tmp/gopath/pkg/mod/cache/vcs/12330e8f12b843c19322388d9f726ba65c92be1dda46cd6a348f373be8edd50d: exit status 128:\n\t\tfatal: could not read Username for 'https://github.com': terminal prompts disabled\n\tConfirm the import path was entered correctly.\n\tIf this is a private repository, see https://golang.org/doc/faq#git_https for additional information.\n  ```\n  please setup private repo via command: `export GOPRIVATE=github.com/linhbkhn95/*` and `git config --global url.https://${{ PERSONAL_ACCESS_TOKEN }}@github.com/.insteadOf https://github.com/`\n\n\n2. install grpc folder: run `git clone git@github.com:linhbkhn95/rpc-proto.git`.\n\n3. cd module need to use then run `go generate`.\n\n4. you can edit flag at header of file main.go before generate: `go:generate go run gen.go grpc_server --rpc_protos=health/v1/health.proto`.\n\n## Layout module\nIt is really `rpc-framework` which will init project and make layout for your project. It will read `proto` file from `proto` path which defined. It include all of `GRPC` interface. So, It can generate something which you need like (`RPC` instance, handler implementation ...)\n\nExample: when run init project `example` which combine by two services `health` and `example`.\nYou should run command: (should run in folder which contains `rpc-proto` dir)\n```\nrpc-framework --project_name=example --go_module_name=github.com/linhbkhn95/example --rpc_proto_dir=rpc-proto/proto --rpc_protos=health/v1/service.proto,example/v1/service.proto\n```\n\nWhen you run command above, you should see like something below.\n\n ```\n 2022/07/27 00:25:26 File was generate at example/config/config.go\n2022/07/27 00:25:26 File was generate at example/server/server.go\n2022/07/27 00:25:27 File was generate at example/server/grpc/server.go\n2022/07/27 00:25:27 File was generate at example/server/handler/health.go\n2022/07/27 00:25:27 File was generate at example/cmd/main.go\n2022/07/27 00:25:27 File was generate at example/.gitignore\n2022/07/27 00:25:27 File was generate at example/go.mod\n2022/07/27 00:25:27 File was generate at example/Makefile\n2022/07/27 00:25:27 File was generate at example/.gitignore\n2022/07/27 00:25:27 Generated completed!\n2022/07/27 00:25:27 installing dependencies ...\n2022/07/27 00:25:27 installing grpc ecosystem ...\n2022/07/27 00:25:27 installing viper...\n2022/07/27 00:25:27 installing github.com/linhbkhn95/golang-british ...\n2022/07/27 00:25:35 installing github.com/linhbkhn95/grpc-service ...\n2022/07/27 00:25:40 installing google.golang.org/grpc ...\n2022/07/27 00:25:41 installing github.com/grpc-ecosystem/go-grpc-middleware ...\n2022/07/27 00:25:42 installing github.com/grpc-ecosystem/grpc-gateway/v2/runtime ...\n2022/07/27 00:25:42 installing github.com/prometheus/client_golang/prometheus/promhttp ...\n2022/07/27 00:25:43 installing google.golang.org/grpc ...\n2022/07/27 00:25:43 installing google.golang.org/grpc/credentials/insecure ...\n2022/07/27 00:25:44 installing google.golang.org/protobuf/encoding/protojson ...\n2022/07/27 00:25:44 installing github.com/grpc-ecosystem/go-grpc-prometheus ...\n2022/07/27 00:25:45 run go mod tidy ...\n2022/07/27 00:25:45 install successfully ..\n ```\n\nthe result like here.\nhttps://github.com/linhbkhn95/grpc-scaffolding/tree/main/example\n\n ## Module flags\n* Grpc server\n  - `rpc_protos`: list service from project grpc, default value: `health/v1/service.proto`.\n  - `enable_gateway`: flag use enable gateway for server, default value: `false`.\n  - `output_path`: goal path then generate, default value: `grpc_server/output/z_server_grpc.go`.\n  - `rpc_proto_dir`: Folder contain services of project, default value : `../rpc-proto/proto`.\n  - `enable_metric`: flag to enable metric by prometheus module. default value: `false`.\n  - `enable_http`: fag to enable port http, default value: `true`.\n\n* Layout\n It will contain all of flags of `grpc_server` and add 2 flags flag is `project_name` and `go_module_name` . So, You should run command \n ```\n rpc-framework --project_name=example --go_module_name=github.com/linhbkhn95/example --rpc_proto_dir=rpc-proto/proto --rpc_protos=health/v1/service.proto,example/v1/service.proto\n ```\n\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinhbkhn95%2Fgrpc-scaffolding","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinhbkhn95%2Fgrpc-scaffolding","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinhbkhn95%2Fgrpc-scaffolding/lists"}