Coder Social home page Coder Social logo

go-kratos / kratos-layout Goto Github PK

View Code? Open in Web Editor NEW
378.0 18.0 199.0 256 KB

Kratos Project Template

Home Page: http://go-kratos.dev

License: MIT License

Go 72.99% Makefile 22.86% Dockerfile 4.16%
golang service layout kratos template project micorservices architecture

kratos-layout's People

Contributors

3139487747 avatar chcaty avatar codingknees avatar daemon365 avatar deepziyu avatar demomanito avatar emptywang avatar endlessidea avatar ggxxll avatar gopower avatar jakseer avatar julian-chu avatar leyou240 avatar longxboy avatar minicloudsky avatar mo3et avatar moecasts avatar pauky avatar qshuai avatar shenqidebaozi avatar songzhibin97 avatar stephenchen avatar storyicon avatar texousliu avatar tonybase avatar windfarer avatar wuxingzhong avatar xiongpan828 avatar xushuhui avatar xx1906 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  avatar  avatar

kratos-layout's Issues

[Question] 配置文件的路径问题

默认的configs寻找路径是向上两级,从这段代码看出应该是为了配合kratos run命令,因为这个命令的work dir是./cmd/server。

但一般项目启动都是在项目根目录下,例如使用make build命令生成bin文件后,直接运行bin文件时configs路径查找总是不正确的,也就是kratos run和bin直接启动总有一种会有问题。

是否有必要考虑重新组织一下目录结构?或者应该交给kratos framework来解决,比如修改一下kratos run的work dir?

make build 生成的二进制文件名和 Dockerfile CMD 启动名不一样

目前 make build 默认生成二进制文件为项目名称,而 Dockerfile CMD 里面写死了 ./server
例如:

  • kratos new helloworld
  • docker build -t helloworld:v0.1.0 .
  • 那么镜像内的二进制文件名称是helloworld

建议:

  • make build 时制定生产的二进制文件名为server
  • 或者在 kratos new 时替换 Dockerfile 中的 CMD

获得效果:

  • 更丝滑的上手体验

layout 优化

@Terry-Mao
Layout 有几个优化

  • Usecase 需要定义在 biz 中;
  • Usecase 出入参为 DTO(解决以前模式里,service 传递 Usecase 参数过多的问题),Usecase 负责 DTO 到 DO 转换,反之亦然;
  • Usecase 只负责控制编排;
  • biz 的 errors 需要定义,可以不依赖 kratos,直接用标准库 errors.New,需要在 Usecase 转换成 kratos errors,需要思考下 mapping 映射
  • 分页规范化
  • field_mask示例
  • 实现 book 示例

Failed to run `go generate ./...` after created a project with `kratos new`

复现步骤:

  1. kratos new playground 创建一个工程。
  2. cd playground 进入工程。
  3. 直接执行 go generate ./... (而非 make generate)。

然后就会遇到这个错误:

➜  playground go generate ./...
/Users/kvii/go/pkg/mod/github.com/google/[email protected]/cmd/wire/main.go:34:2: missing go.sum entry for module providing package github.com/google/subcommands (imported by github.com/google/wire/cmd/wire); to add:
        go get github.com/google/wire/cmd/[email protected]
/Users/kvii/go/pkg/mod/github.com/google/[email protected]/internal/wire/copyast.go:21:2: missing go.sum entry for module providing package golang.org/x/tools/go/ast/astutil (imported by github.com/google/wire/internal/wire); to add:
        go get github.com/google/wire/internal/[email protected]
/Users/kvii/go/pkg/mod/github.com/google/[email protected]/internal/wire/parse.go:30:2: missing go.sum entry for module providing package golang.org/x/tools/go/packages (imported by github.com/google/wire/internal/wire); to add:
        go get github.com/google/wire/internal/[email protected]
/Users/kvii/go/pkg/mod/github.com/google/[email protected]/internal/wire/analyze.go:26:2: missing go.sum entry for module providing package golang.org/x/tools/go/types/typeutil (imported by github.com/google/wire/cmd/wire); to add:
        go get github.com/google/wire/cmd/[email protected]
cmd/playground/wire_gen.go:3: running "go": exit status 1

make build生成版本信息时如果没有初始化git,会报错

What happened:

通过kratos命令创建好模板项目后,直接执行make build会报错 fatal: 不是 git 仓库

What you expected to happen:

make build 生成版本信息的时候不应该强依赖 git,建议如果没有初始化git的时候用时间戳做版本

How to reproduce it (as minimally and precisely as possible):

Anything else we need to know?:

Environment:

  • Kratos version (use kratos -v): v2.0.0-beta4
  • Go version (use go version): go1.16
  • OS (e.g: cat /etc/os-release):
  • Others:

多个service依赖应该怎么组织代码

比如在同一个进程内有 用户service, 积分service, 当用户升级的时候, 增加用户的积分, 这个操作应该写在哪里

用户service应该依赖于积分service?
还是用户biz依赖于积分biz?

Git_Bash in the Makefile is not necessary

Git_Bash in the Makefile as follows are not necessary!
Because if the user is working on Windows, the user needs to install a tool like cygwin64 in order to use the make command, the bash.exe and make.exe must have been added to the Windows environment variable Path.
So, simply replace $(Git_Bash) with bash. As shown below:

...
INTERNAL_PROTO_FILES=$(shell bash -c "find internal -name *.proto")
API_PROTO_FILES=$(shell bash -c "find api -name *.proto")
ifeq ($(GOHOSTOS), windows)
    #the `find.exe` is different from `find` in bash/shell.
    #to see https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/find.
    #changed to use git-bash.exe to run find cli or other cli friendly, caused of every developer has a Git.
    Git_Bash= $(subst cmd\,bin\bash.exe,$(dir $(shell where git)))
    INTERNAL_PROTO_FILES=$(shell $(Git_Bash) -c "find internal -name *.proto")
    API_PROTO_FILES=$(shell $(Git_Bash) -c "find api -name *.proto")

go generate ./... 到了这步骤就报错了。

go version 1.16.7
kratos 2.0.5

按照这个步骤来的:

# Create a template project
kratos new server

cd server
# Add a proto template
kratos proto add api/server/server.proto
# Generate the proto code
kratos proto client api/server/server.proto
# Generate the source code of service by proto file
kratos proto server api/server/server.proto -t internal/service

go generate ./...
go build -o ./bin/ ./...
./bin/server -conf ./configs

具体报错如下:

D:\code\src\server>go generate ./...
google/protobuf/descriptor.proto: File not found.
errors/errors.proto:10:1: Import "google/protobuf/descriptor.proto" was not found or had errors.
errors/errors.proto:12:8: "google.protobuf.EnumOptions" is not defined.
errors/errors.proto:16:8: "google.protobuf.EnumValueOptions" is not defined.
api/helloworld/v1/error_reason.proto:4:1: Import "errors/errors.proto" was not found or had errors.
exit status 1
D:\code\pkg\mod\github.com\google\[email protected]\internal\wire\copyast.go:21:2: missing go.sum entry for module providing package golang.org/x/tools/go/ast/astutil (imported by github.com/google/wire/internal/wire); to add:
        go get github.com/google/wire/internal/[email protected]
D:\code\pkg\mod\github.com\google\[email protected]\internal\wire\parse.go:30:2: missing go.sum entry for module providing package golang.org/x/tools/go/packages (imported by github.com/google/wire/internal/wire); to add:
        go get github.com/google/wire/internal/[email protected]
D:\code\pkg\mod\github.com\google\[email protected]\internal\wire\analyze.go:26:2: missing go.sum entry for module providing package golang.org/x/tools/go/types/typeutil (imported by github.com/google/wire/cmd/wire); to add:
        go get github.com/google/wire/cmd/[email protected]
cmd\server\wire_gen.go:3: running "go": exit status 1

[Question] NewGreeterRepo 为什么考虑返回 Interface 而不是 具体类型

[Question] NewGreeterRepo 为什么考虑返回 Interface 而不是具体类型

Data 层这里 NewGreeterRepo 为什么返回 Interface 而不是 greeterRepo 类型;我看到 Go 这里的最佳实践是 返回具体类型;目前返回 Interface 是出于什么考虑?

type greeterRepo struct {
	data *Data
	log  *log.Helper
}

// NewGreeterRepo .
func NewGreeterRepo(data *Data, logger log.Logger) biz.GreeterRepo {
	return &greeterRepo{
		data: data,
		log:  log.NewHelper(logger),
	}
}

need best practice for multi models

thanks for provide this layout, but when i try my first project(name it blog), i find some issues:

  1. kratos new blog does not rename api/helloworld to api/blog, but cmd/helloworld renamed to cmd/blog as expected.

  2. for multi models, the folder structure has no demo. How about group them in folder by model in api? but this change let package name v1 no longer work. same consideration to biz, data, service.

├── api
│   └── blog
│       └── v1
│           └── error_reason
│               ├── error_reason.proto
│               ├── error_reason.pb.go
│               ├── error_reason.swagger.json
│           └── article
│               ├── article.proto
│               ├── article.pb.go
│               ├── article.swagger.json
│               ├── article_grpc.pb.go
│               └── article_http.pb.go
│           └── comment
│               ├── comment.proto
│               ├── comment.pb.go
│               ├── comment.swagger.json
│               ├── comment_grpc.pb.go
│               └── comment_http.pb.go
  1. how about move conf and server to the root folder? unlike biz, data, service which is model level, they are project level IMO.
├── internal
│   ├── biz
│   │   ├── README.md
│   │   ├── biz.go
│   │   └── greeter.go
│   ├── conf // move to project root folder as it is project level?
│   │   ├── conf.pb.go
│   │   └── conf.proto
│   ├── data
│   │   ├── README.md
│   │   ├── data.go
│   │   └── greeter.go
│   ├── server // move to project root folder as it is project level?
│   │   ├── grpc.go
│   │   ├── http.go
│   │   └── server.go
│   └── service
│       ├── README.md
│       ├── greeter.go
│       └── service.go
  1. register muli service
    multi models means multi service, how to register multi services to one server? below should work,
    but they are hard coded, not sure is there a better way?
func NewHTTPServer(
    c *conf.Server, 
    greeter *service.GreeterService, 
    article *service.ArticleService, 
    comment *service.CommentService, 
    logger log.Logger,
) *http.Server {
        // ... omited 
	srv := http.NewServer(opts...)
	v1.RegisterGreeterHTTPServer(srv, greeter)
        v1.RegisterArticleHTTPServer(srv, article)
        v1.RegisterCommentHTTPServer(srv, comment)
	return srv
}

I know there is a examples/blog but it is too simple only have one model,
maybe we can make it more realistic to show more feature and best practise of use kartos?

thanks.

创建模板错误

kratos new helloworld

找不到错误原因。
报错了:
ERROR: Failed to create project(exit status 128)

Dockerfile 中是否可以添加先下载依赖的逻辑?

可以在 Dockerfile 中添加下面的逻辑:

# 先下载依赖。
COPY go.mod .
COPY go.sum .
RUN go mod download

# 然后再拷贝工程文件并打包。
COPY . .
RUN go build ...
...

加上这样一段逻辑后,如果工程的依赖版本没有变动的话,再次构建镜像时就会跳过下载依赖的步骤。这样就能减少下载依赖的时间。减少本地调试或频繁发板时的等待时间。

The Git_Bash in the Makefile is necessary to optimize

The current Git_Bash does not support paths with spaces and does not support the "\" path for Linux Shell.
It is also not easy to use.
So whether Windows or Linux, the best solution is just to replace find with /usr/bin/find. As follows shown:

INTERNAL_PROTO_FILES=$(shell /usr/bin/find -c "find internal -name *.proto")
API_PROTO_FILES=$(shell /usr/bin/find -c "find api -name *.proto")

generate报错

报错信息(go generate ./...make generate):

no required module provides package github.com/google/wire/cmd/wire; to add it:
	go get github.com/google/wire/cmd/wire
cmd/pagination/wire_gen.go:3: running "go": exit status 1

按提示执行go get github.com/google/wire/cmd/wire后也不行。

相关信息:

kratos version v2.4.0
go version go1.18.3 darwin/amd64

maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined

mac os环境,make build之后,启动程序,报这个错

$ bin/server
2022/10/30 22:06:08 maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined
panic: stat ../../configs: no such file or directory

goroutine 1 [running]:
main.main()
/Users/xx/go/kratos-layout/cmd/server/main.go:69 +0x677

Makefile和third_party的openapi版本不一致

Client.Invoke CallOption 无效

client := v1.NewGreeterHTTPClient(httpClient)
client.SayHello(context.Background(), &v1.HelloRequest{}, http.Operation("/helloxxx")) // 指定Operation

func (c *GreeterHTTPClientImpl) SayHello(ctx context.Context, in *HelloRequest, opts ...http.CallOption) (*HelloReply, error) {
	var out HelloReply
	pattern := "/helloworld/{name}"
	path := binding.EncodeURL(pattern, in, true)
        // 指定的Operation在前,被以下语句添加的Operation覆盖
	opts = append(opts, http.Operation("/helloworld.v1.Greeter/SayHello"))
	opts = append(opts, http.PathTemplate(pattern))
	err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
	if err != nil {
		return nil, err
	}
	return &out, err
}

Use "**/*.proto" to match proto files

I can execute this command to compile all '.proto' files.

protoc --proto_path=./api -proto_path=./third_party --go_out=paths=source_relative:./api api/**/*.proto

Note I've used "api/**/*.proto" to match proto fille in all subdirectories. It's more elegant than use find command in Makefile. Can we use it in Makefile?

Code "it's hard to use find on windows":

kratos-layout/Makefile

Lines 5 to 16 in ba85299

ifeq ($(GOHOSTOS), windows)
#the `find.exe` is different from `find` in bash/shell.
#to see https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/find.
#changed to use git-bash.exe to run find cli or other cli friendly, caused of every developer has a Git.
#Git_Bash= $(subst cmd\,bin\bash.exe,$(dir $(shell where git)))
Git_Bash=$(subst \,/,$(subst cmd\,bin\bash.exe,$(dir $(shell where git))))
INTERNAL_PROTO_FILES=$(shell $(Git_Bash) -c "find internal -name *.proto")
API_PROTO_FILES=$(shell $(Git_Bash) -c "find api -name *.proto")
else
INTERNAL_PROTO_FILES=$(shell find internal -name *.proto)
API_PROTO_FILES=$(shell find api -name *.proto)
endif

[Question] 为什么 repo 的函数都需要加后缀呢

关于代码结构一直有个地方没想明白,比如这个示例

type ArticleRepo interface {
	// db
	ListArticle(ctx context.Context) ([]*Article, error)
	GetArticle(ctx context.Context, id int64) (*Article, error)
	CreateArticle(ctx context.Context, article *Article) error
	UpdateArticle(ctx context.Context, id int64, article *Article) error
	DeleteArticle(ctx context.Context, id int64) error

	// redis
	GetArticleLike(ctx context.Context, id int64) (rv int64, err error)
	IncArticleLike(ctx context.Context, id int64) error
}

type ArticleUsecase struct {
	repo ArticleRepo
}

func NewArticleUsecase(repo ArticleRepo, logger log.Logger) *ArticleUsecase {
	return &ArticleUsecase{repo: repo}
}

func (uc *ArticleUsecase) List(ctx context.Context) (ps []*Article, err error) {
	ps, err = uc.repo.ListArticle(ctx)
	if err != nil {
		return
	}
	return
}

为什么usecase不需要后缀,而repo需要Article后缀呢。每次都加后缀的话,如果对象命名比较长,那么repo的函数名也会很长呢

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.