Skip to content

Commit

Permalink
fix the issue that appearing in initializing go-coco project (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
kid551 authored Apr 12, 2024
1 parent a9e1286 commit 4f7485c
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 4 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@

## Getting Started

使用 go-coco cli 构建一个新项目:
```bash
# 安装 go-coco cli
go install github.com/iftechio/go-coco@latest

# 创建项目目录
mkdir <proj_root>
cd <proj_root>

# 确保 `go-coco` 在包含 `go.mod` 的目录下运行
go mod init <app_name>

go-coco init <micro_service_name>
```

Notes:
1. 使用 `app.Manager` 组织需要启动的微服务应用
2. 使用 `config` 解析来自 toml 和 env 的应用变量配置
3. 使用 `infra` 快速构建基础层组件
Expand Down
143 changes: 143 additions & 0 deletions app/server/xgrpc/gateway.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package xgrpc

import (
"context"
"fmt"
"net/http"
"strings"

"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
xLogger "github.com/iftechio/go-coco/utils/logger"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/runtime/protoimpl"
"google.golang.org/protobuf/types/known/structpb"
)

type CustomError struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields

Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
Toast *string `protobuf:"bytes,2,opt,name=toast,proto3,oneof" json:"toast,omitempty"`
// E Code
Code *string `protobuf:"bytes,3,opt,name=code,proto3,oneof" json:"code,omitempty"`
Error *string `protobuf:"bytes,4,opt,name=error,proto3,oneof" json:"error,omitempty"`
Data *structpb.Value `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"`
}

func GatewayMiddleware(
register func(
ctx context.Context,
mux *runtime.ServeMux,
endpoint string,
opts []grpc.DialOption,
) (err error),
endpoint string,
pattern string,
) echo.MiddlewareFunc {
gateway := runtime.NewServeMux(
runtime.WithIncomingHeaderMatcher(func(s string) (string, bool) {
switch s {
case "Connection":
return "", false
default:
return s, true
}
}),
runtime.WithErrorHandler(gatewayErrorHandler),
runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.HTTPBodyMarshaler{
Marshaler: &runtime.JSONPb{
MarshalOptions: protojson.MarshalOptions{
UseProtoNames: true,
EmitUnpopulated: true,
},
UnmarshalOptions: protojson.UnmarshalOptions{
DiscardUnknown: true,
},
},
}),
)
if err := register(
context.Background(), gateway, endpoint, []grpc.DialOption{grpc.WithInsecure()},
); err != nil {
panic(err)
}
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
if strings.HasPrefix(c.Path(), pattern) {
gateway.ServeHTTP(c.Response(), c.Request())
return nil
}
return next(c)
}
}
}

// gatewayErrorHandler 自定义 error handler
// 覆盖 runtime.DefaultErrorHandle 默认的错误处理,实现自定义的 error payload
func gatewayErrorHandler(
ctx context.Context,
mux *runtime.ServeMux,
marshaler runtime.Marshaler,
w http.ResponseWriter,
r *http.Request,
err error,
) {
var statusCode int
var customStatus *runtime.HTTPStatusError
if errors.As(err, &customStatus) {
err = customStatus.Err
statusCode = customStatus.HTTPStatus
}

s := status.Convert(err)

pb := &CustomError{
Message: s.Message(),
}

for _, d := range s.Details() {
m, ok := d.(*CustomError)
if !ok {
continue
}
pb.Message = m.Message
pb.Error = m.Toast
pb.Code = m.Code
pb.Data = m.Data
}

w.Header().Del("Trailer")
w.Header().Del("Transfer-Encoding")
w.Header().Set("Content-Type", marshaler.ContentType(pb))

buf, merr := marshaler.Marshal(pb)
if merr != nil {
w.WriteHeader(http.StatusInternalServerError)
xLogger.F(ctx).Errorf("Failed to marshal error message %q: %v", s, merr)
return
}

if md, ok := runtime.ServerMetadataFromContext(ctx); ok {
for k, vs := range md.HeaderMD {
h := fmt.Sprintf("%s%s", runtime.MetadataHeaderPrefix, k)
for _, v := range vs {
w.Header().Add(h, v)
}
}
}

if statusCode == 0 {
statusCode = runtime.HTTPStatusFromCode(s.Code())
}

w.WriteHeader(statusCode)
if _, err := w.Write(buf); err != nil {
xLogger.F(ctx).Errorf("Failed to write response: %v", err)
}
}
3 changes: 3 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ type CurDir struct {
func modInfoJSON(args ...string) []byte {
cmdArgs := append([]string{"list", "-json"}, args...)
out, err := exec.Command("go", cmdArgs...).Output()
if len(out) == 0 {
panic("No 'go.mod' found, please make sure to run 'go-coco' in golang project directory containing 'go.mod' file.")
}
cobra.CheckErr(err)
return out
}
7 changes: 7 additions & 0 deletions cmd/tpl/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ func (s *Server) Start() error {
s.srv.Use(middleware.Sentry())
{{- end }}
// TODO: Add Routings
{{- if .WithProto }}
s.srv.Use(xgrpc.GatewayMiddleware(
public.RegisterPublicServiceHandlerFromEndpoint,
s.conf.GRPCAddr,
"/1.0",
))
{{ end }}
{{- if .WithProto }}
// Swagger Doc
s.srv.GET("/swagger/*", echo.WrapHandler(http.FileServer(http.FS(swagger))))
Expand Down
2 changes: 1 addition & 1 deletion cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var versionCmd = &cobra.Command{
Short: "Print the version number of go-coco",
Long: `All software has versions. This is go-coco's`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("go-coco Generator v1.3.6")
fmt.Println("go-coco Generator v0.0.2")
},
}

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/go-redis/redis/v8 v8.11.4
github.com/google/gops v0.3.17
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.13.0
github.com/labstack/echo/v4 v4.6.1
github.com/labstack/gommon v0.3.0
github.com/pkg/errors v0.9.1
Expand All @@ -28,6 +29,7 @@ require (
go.mongodb.org/mongo-driver v1.5.3
golang.org/x/text v0.4.0
google.golang.org/grpc v1.50.1
google.golang.org/protobuf v1.28.1
)

require (
Expand All @@ -47,7 +49,6 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jcchavezs/porto v0.1.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
Expand Down Expand Up @@ -91,7 +92,6 @@ require (
golang.org/x/tools v0.1.12 // indirect
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect
google.golang.org/grpc/examples v0.0.0-20220413171549-7567a5d96538 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.0 // indirect
Expand Down
4 changes: 3 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down Expand Up @@ -163,7 +164,6 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gops v0.3.17 h1:CguOcnDVYG32soOj2YevV8mW9asrIh1lZw3d7Ovty/o=
Expand All @@ -174,6 +174,8 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.13.0 h1:fi9bGIUJOGzzrHBbP8NWbTfNC5fKO6X7kFw40TOqGB8=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.13.0/go.mod h1:uY3Aurq+SxwQCpdX91xZ9CgxIMT1EsYtcidljXufYIY=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
Expand Down

0 comments on commit 4f7485c

Please sign in to comment.