Kratos Service Layout

Kratos Layout

Install Kratos

go get github.com/go-kratos/kratos/cmd/kratos
go get github.com/go-kratos/kratos/cmd/protoc-gen-go-http
go get github.com/go-kratos/kratos/cmd/protoc-gen-go-errors

# from source
cd cmd/kratos && go install
cd cmd/protoc-gen-go-http && go install
cd cmd/protoc-gen-go-errors && go install

Create a service

# create a template project
kratos new helloworld

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

make proto
make build
make test
Owner
Kratos
A Go framework for microservices.
Kratos
Comments
  • [Question] 配置文件的路径问题

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

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

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

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

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

    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
    
    
  • make build 生成的二进制文件名和 Dockerfile CMD 启动名不一样

    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

    获得效果:

    • 更丝滑的上手体验
  • Makefile和third_party的openapi版本不一致

    Makefile和third_party的openapi版本不一致

    在Makefile里面, 生成的openapi版本是v3.0.x的 https://github.com/go-kratos/kratos-layout/blob/main/Makefile#L14

    third_party的proto文件 https://github.com/go-kratos/kratos-layout/tree/main/third_party/protoc-gen-openapiv2/options 使用的是grpc-gateway的openapiv2 https://github.com/grpc-ecosystem/grpc-gateway/tree/master/protoc-gen-openapiv2/options

    要不要把third_party的proto文件换成openapiv3的呢? https://github.com/google/gnostic/blob/master/openapiv3/OpenAPIv3.proto

  • 创建项目报错

    创建项目报错

    kratos new helloworld kratos new helloworld -r https://gitee.com/go-kratos/kratos-layout.git

    都报错,同样的错 ERROR: Failed to create project(exit status 128)

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

    [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的函数名也会很长呢

  • Client.Invoke CallOption 无效

    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
    }
    
  • [Question] NewGreeterRepo 为什么考虑返回 Interface 而不是 具体类型

    [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),
    	}
    }
    
  • make build生成版本信息时如果没有初始化git,会报错

    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:
  • Git_Bash in the Makefile is not necessary

    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")
    
  • maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined

    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

  • The Git_Bash in the Makefile is necessary to optimize

    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")
    
  • Use ditroless base image rather than debian slim

    Use ditroless base image rather than debian slim

    The current base image with debian slim has the following package dependency

    https://github.com/go-kratos/kratos-layout/blob/ce6c357221295296cd224502de69bda79c69f438/Dockerfile#L10-L12

    It's actually covered by https://gcr.io/distroless/static-debian11 and even lighter than the slim image.

    https://github.com/GoogleContainerTools/distroless/blob/main/gcscache/internal/dpkg/info.go

  • need best practice for multi models

    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.

  • layout 优化

    layout 优化

    @Terry-Mao Layout 有几个优化

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

A service health dashboard in Go that is meant to be used as a docker image with a custom configuration file. I personally deploy it in my Kubernetes

Dec 31, 2022
HTTP service to generate PDF from Json requests

pdfgen HTTP service to generate PDF from Json requests Install and run The recommended method is to use the docker container by mounting your template

Dec 2, 2022
An HTTP service for customizing import path of your Go packages.

Go Packages A self-host HTTP service that allow customizing your Go package import paths. Features Reports. Badges. I18N. Preview I launch up a free H

Nov 27, 2022
A service for predicting the order of keys to use for opening doors in Ladder Slasher

A service for predicting the order of keys to use for opening doors in Ladder Slasher.

Oct 29, 2021
Service for firewalling graphite metrics

hadrianus Block incoming graphite metrics if they come in too fast for downstream carbon-relay/carbon-cache to handle. Building Hadrianus is written i

Apr 28, 2022
Example hello-world service uses go-fx-grpc-starter boilerplate code

About Example hello-world service uses https://github.com/srlk/go-fx-grpc-starter boilerplate code. Implementation A hello world grpc service is creat

Nov 14, 2021
Typesafe lazy instantiation to improve service start time

Package lazy is a light wrapper around sync.Once providing support for return values. It removes the burden of capturing return values via closures from the caller.

May 30, 2022
Implement a toy in-memory store information service for a delivery company

Implement a toy in-memory store information service for a delivery company

Nov 22, 2021
An in-memory, key-value store HTTP API service

This is an in-memory key-value store HTTP API service, with the following endpoints: /get/{key} : GET method. Returns the value of a previously set ke

May 23, 2022
A Simple Bank Web Service implemented in Go, HTTP & GRPC, PostgreSQL, Docker, Kubernetes, GitHub Actions CI

simple-bank Based on this Backend Master Class by TECH SCHOOL: https://youtube.com/playlist?list=PLy_6D98if3ULEtXtNSY_2qN21VCKgoQAE Requirements Insta

Dec 9, 2021
Golang service boilerplate using best practices

go-boilerplate Golang service boilerplate using best practices. Responsibility: Register (CRUD) and Login Users with JWT. Dependencies Gin-Gonic Swagg

May 11, 2022
The Bhojpur BSS is a software-as-a-service product used as an Business Support System based on Bhojpur.NET Platform for application delivery.

Bhojpur BSS - Business Support System The Bhojpur BSS is a software-as-a-service product used as an Business Support System based on Bhojpur.NET Platf

Sep 26, 2022
This contains some example (micro)service

This contains some example (micro)service. It should expose some of the issues when tyring to put too much logic into one file or to mix things that should not be mixed together.

Jan 11, 2022
Kratos is a microservice-oriented governance framework implements by golang
Kratos is a microservice-oriented governance framework implements by golang

Kratos is a microservice-oriented governance framework implements by golang, which offers convenient capabilities to help you quickly build a bulletproof application from scratch.

Dec 27, 2022
An online shop application, the complete microservices demo for kratos.

[WIP] beer-shop An online shop application, the complete microservices demo for kratos. 本项目为一个使用kratos框架创建的,简单却功能尽量完整的微服务电商项目。旨在演示kratos在mono-repo(单体仓

Jan 6, 2023
Kratos is a microservice-oriented governance framework implements by golang,
Kratos is a microservice-oriented governance framework implements by golang,

Kratos is a microservice-oriented governance framework implements by golang, which offers convenient capabilities to help you quickly build a bulletproof application from scratch.

Dec 31, 2022
基于go-kratos +Ant Design Pro的前后端分离微服务管理系统后端模块
基于go-kratos +Ant Design Pro的前后端分离微服务管理系统后端模块

项目前端是基于Ant Design Pro来创建的,后端是基于go-kratos来创建的一个前后端分离的管理系统

Nov 24, 2022
Kratos Project Template

Kratos Project Template Install Kratos go get -u github.com/go-kratos/kratos/cmd/kratos/v2@latest Create a service # Create a template project kratos

Feb 22, 2022
Kratos Project Template for golang

Kratos Project Template Install Kratos go get -u github.com/go-kratos/kratos/cmd/kratos/v2@latest Create a service # Create a template project kratos

Dec 11, 2021
Ares-admin - Kratos Project Template For Golang

Kratos Project Template Install Kratos go get -u github.com/go-kratos/kratos/cmd

Feb 15, 2022