From fcbe60060633620cc342eced32a5d0799c8110ec Mon Sep 17 00:00:00 2001 From: kzkzzzz Date: Tue, 12 Jul 2022 09:54:27 +0800 Subject: [PATCH] feat: init --- api/job/{.gitignore => .gitkeep} | 0 app/service/{.gitignore => .gitkeep} | 0 app/service/demo/.gitignore | 2 + app/service/demo/Dockerfile | 24 ++++ app/service/demo/air.toml | 37 ++++++ app/service/demo/cmd/demo/main.go | 113 ++++++++++++++++++ app/service/demo/cmd/demo/wire.go | 22 ++++ app/service/demo/cmd/demo/wire_gen.go | 36 ++++++ app/service/demo/config/config.yaml | 37 ++++++ app/service/demo/internal/biz/biz.go | 6 + app/service/demo/internal/biz/demo.go | 78 ++++++++++++ app/service/demo/internal/conf/conf.go | 56 +++++++++ app/service/demo/internal/data/data.go | 37 ++++++ app/service/demo/internal/data/demo.go | 52 ++++++++ app/service/demo/internal/model/demo.go | 13 ++ app/service/demo/internal/server/grpc.go | 35 ++++++ app/service/demo/internal/server/http.go | 39 ++++++ .../demo/internal/server/middleware.go | 25 ++++ app/service/demo/internal/server/server.go | 12 ++ app/service/demo/internal/service/convert.go | 16 +++ app/service/demo/internal/service/demo.go | 77 ++++++++++++ app/service/demo/internal/service/service.go | 6 + app/service/demo/openapi.yaml | 39 ++++++ 23 files changed, 762 insertions(+) rename api/job/{.gitignore => .gitkeep} (100%) rename app/service/{.gitignore => .gitkeep} (100%) create mode 100644 app/service/demo/.gitignore create mode 100644 app/service/demo/Dockerfile create mode 100644 app/service/demo/air.toml create mode 100644 app/service/demo/cmd/demo/main.go create mode 100644 app/service/demo/cmd/demo/wire.go create mode 100644 app/service/demo/cmd/demo/wire_gen.go create mode 100644 app/service/demo/config/config.yaml create mode 100644 app/service/demo/internal/biz/biz.go create mode 100644 app/service/demo/internal/biz/demo.go create mode 100644 app/service/demo/internal/conf/conf.go create mode 100644 app/service/demo/internal/data/data.go create mode 100644 app/service/demo/internal/data/demo.go create mode 100644 app/service/demo/internal/model/demo.go create mode 100644 app/service/demo/internal/server/grpc.go create mode 100644 app/service/demo/internal/server/http.go create mode 100644 app/service/demo/internal/server/middleware.go create mode 100644 app/service/demo/internal/server/server.go create mode 100644 app/service/demo/internal/service/convert.go create mode 100644 app/service/demo/internal/service/demo.go create mode 100644 app/service/demo/internal/service/service.go create mode 100644 app/service/demo/openapi.yaml diff --git a/api/job/.gitignore b/api/job/.gitkeep similarity index 100% rename from api/job/.gitignore rename to api/job/.gitkeep diff --git a/app/service/.gitignore b/app/service/.gitkeep similarity index 100% rename from app/service/.gitignore rename to app/service/.gitkeep diff --git a/app/service/demo/.gitignore b/app/service/demo/.gitignore new file mode 100644 index 0000000..b8a9061 --- /dev/null +++ b/app/service/demo/.gitignore @@ -0,0 +1,2 @@ +bin +tmp \ No newline at end of file diff --git a/app/service/demo/Dockerfile b/app/service/demo/Dockerfile new file mode 100644 index 0000000..4b196fb --- /dev/null +++ b/app/service/demo/Dockerfile @@ -0,0 +1,24 @@ +FROM golang:1.16 AS builder + +COPY ../../demo /src +WORKDIR /src + +RUN GOPROXY=https://goproxy.cn make build + +FROM debian:stable-slim + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + netbase \ + && rm -rf /var/lib/apt/lists/ \ + && apt-get autoremove -y && apt-get autoclean -y + +COPY --from=builder /src/bin /app + +WORKDIR /app + +EXPOSE 8000 +EXPOSE 9000 +VOLUME /data/conf + +CMD ["./server", "-conf", "/data/conf"] diff --git a/app/service/demo/air.toml b/app/service/demo/air.toml new file mode 100644 index 0000000..8107089 --- /dev/null +++ b/app/service/demo/air.toml @@ -0,0 +1,37 @@ +root = "." +testdata_dir = "bin" +tmp_dir = "bin" + +[build] +args_bin = [] +bin = "./bin/demo" +cmd = "go build -o bin/ ./..." +full_bin = "" +delay = 1000 +exclude_dir = ["bin", "assets", "tmp", "vendor", "testdata"] +exclude_file = [] +exclude_regex = ["_test.go"] +exclude_unchanged = false +follow_symlink = false +include_dir = [] +include_ext = ["go", "tpl", "tmpl", "html"] +kill_delay = "0.3s" +log = "build-errors.log" +send_interrupt = true +stop_on_error = true + +[color] +app = "" +build = "yellow" +main = "magenta" +runner = "green" +watcher = "cyan" + +[log] +time = false + +[misc] +clean_on_exit = false + +[screen] +clear_on_rebuild = false diff --git a/app/service/demo/cmd/demo/main.go b/app/service/demo/cmd/demo/main.go new file mode 100644 index 0000000..c1813cc --- /dev/null +++ b/app/service/demo/cmd/demo/main.go @@ -0,0 +1,113 @@ +package main + +import ( + "flag" + "github.com/go-kratos/kratos/contrib/registry/consul/v2" + "github.com/go-kratos/kratos/v2" + "github.com/go-kratos/kratos/v2/middleware/tracing" + "github.com/go-kratos/kratos/v2/transport/grpc" + "github.com/go-kratos/kratos/v2/transport/http" + "github.com/hashicorp/consul/api" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/exporters/jaeger" + "go.opentelemetry.io/otel/sdk/resource" + tracesdk "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.10.0" + "go.uber.org/zap" + "gokratos-base/app/service/demo/internal/conf" + "gokratos-base/common/logz" + "os" + + "github.com/go-kratos/kratos/v2/log" +) + +// go build -ldflags "-X main.Version=x.y.z" +var ( + // Name is the name of the compiled software. + Name string + // Version is the version of the compiled software. + Version string + + id, _ = os.Hostname() +) + +func main() { + flag.Parse() + conf.LoadConfig() + + err := initTracer(conf.Conf.Jaeger.Url) + if err != nil { + panic(err) + } + + l := logz.NewLogger(conf.Conf.Log, zap.AddCaller(), zap.AddCallerSkip(3)) + defer l.Flush() + + logger := log.With(l, + "service.id", id, + "service.name", conf.Conf.Server.Name, + "service.version", conf.Conf.Server.Version, + "trace.id", tracing.TraceID(), + "span.id", tracing.SpanID(), + ) + log.SetLogger(logger) + + app, cleanup, err := wireApp(conf.Conf.Server, conf.Conf.Data, logger) + if err != nil { + panic(err) + } + defer cleanup() + + // start and wait for stop signal + if err := app.Run(); err != nil { + panic(err) + } +} + +func newApp(logger log.Logger, hs *http.Server, gs *grpc.Server) *kratos.App { + cfg := api.DefaultConfig() + cfg.Address = conf.Conf.Consul.Addr + consulClient, err := api.NewClient(cfg) + if err != nil { + panic(err) + } + registry := consul.New(consulClient) + + return kratos.New( + kratos.ID(id), + kratos.Name(conf.Conf.Server.Name), + kratos.Version(conf.Conf.Server.Version), + kratos.Metadata(map[string]string{}), + kratos.Logger(logger), + kratos.Server( + hs, + gs, + ), + kratos.Registrar(registry), + ) +} + +// 设置全局trace +func initTracer(url string) error { + // 创建 Jaeger exporter + exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))) + if err != nil { + return err + } + tp := tracesdk.NewTracerProvider( + // 将基于父span的采样率设置为100% + tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))), + // 始终确保再生成中批量处理 + tracesdk.WithBatcher(exp), + // 在资源中记录有关此应用程序的信息 + tracesdk.WithResource(resource.NewSchemaless( + semconv.ServiceNameKey.String("kratos-trace"), + attribute.String("exporter", "jaeger"), + attribute.Float64("float", 312.23), + )), + ) + + otel.SetTracerProvider(tp) + return nil +} diff --git a/app/service/demo/cmd/demo/wire.go b/app/service/demo/cmd/demo/wire.go new file mode 100644 index 0000000..0fb8a11 --- /dev/null +++ b/app/service/demo/cmd/demo/wire.go @@ -0,0 +1,22 @@ +//go:build wireinject +// +build wireinject + +// The build tag makes sure the stub is not built in the final build. + +package main + +import ( + "github.com/go-kratos/kratos/v2" + "github.com/go-kratos/kratos/v2/log" + "github.com/google/wire" + "gokratos-base/app/service/demo/internal/biz" + "gokratos-base/app/service/demo/internal/conf" + "gokratos-base/app/service/demo/internal/data" + "gokratos-base/app/service/demo/internal/server" + "gokratos-base/app/service/demo/internal/service" +) + +// wireApp init kratos application. +func wireApp(*conf.Server, *conf.Data, log.Logger) (*kratos.App, func(), error) { + panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp)) +} diff --git a/app/service/demo/cmd/demo/wire_gen.go b/app/service/demo/cmd/demo/wire_gen.go new file mode 100644 index 0000000..46aef4e --- /dev/null +++ b/app/service/demo/cmd/demo/wire_gen.go @@ -0,0 +1,36 @@ +// Code generated by Wire. DO NOT EDIT. + +//go:generate go run github.com/google/wire/cmd/wire +//go:build !wireinject +// +build !wireinject + +package main + +import ( + "github.com/go-kratos/kratos/v2" + "github.com/go-kratos/kratos/v2/log" + "gokratos-base/app/service/demo/internal/biz" + "gokratos-base/app/service/demo/internal/conf" + "gokratos-base/app/service/demo/internal/data" + "gokratos-base/app/service/demo/internal/server" + "gokratos-base/app/service/demo/internal/service" +) + +// Injectors from wire.go: + +// wireApp init kratos application. +func wireApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, func(), error) { + dataData, cleanup, err := data.NewData(confData) + if err != nil { + return nil, nil, err + } + demoRepo := data.NewDemoRepo(dataData) + demoUseCase := biz.NewDemoUseCase(demoRepo) + demoService := service.NewDemoService(demoUseCase) + httpServer := server.NewHTTPServer(confServer, demoService) + grpcServer := server.NewGRPCServer(confServer, demoService) + app := newApp(logger, httpServer, grpcServer) + return app, func() { + cleanup() + }, nil +} diff --git a/app/service/demo/config/config.yaml b/app/service/demo/config/config.yaml new file mode 100644 index 0000000..b522321 --- /dev/null +++ b/app/service/demo/config/config.yaml @@ -0,0 +1,37 @@ +# 服务配置 +Server: + Name: "service.demo" + Version: "1.0.0" + Grpc: + Addr: "0.0.0.0:8001" # 为空随机端口, 使用注册中心服务发现 + Timeout: 3 # 服务超时时间, 单位秒 + Http: + Addr: "0.0.0.0:8000" # 为空随机端口, 使用注册中心服务发现 + Timeout: 3 # 服务超时时间, 单位秒 + +# 注册中心 +Consul: + Addr: 192.168.233.1:8500 + +# jaeger链路追踪 https://github.com/jaegertracing/jaeger +Jaeger: + Url: http://192.168.233.1:14268/api/traces + +# 数据源 +Data: + Mysql: + Dsn: temp:temp666@tcp(127.0.0.1:3306)/site?loc=Local&charset=utf8mb4&writeTimeout=3s&readTimeout=3s&timeout=2s&parseTime=true + MaxConn: 16 # 连接池最大连接数 + MaxIdleConn: 4 # 连接池最小连接数 + MaxLifetime: 1800 # 连接池内连接有效时间,单位秒 + Debug: true + + Redis: + Addr: 127.0.0.1:6379 + Password: "" + DB: 15 + +# 日志 +Log: + Color: true + Level: DEBUG \ No newline at end of file diff --git a/app/service/demo/internal/biz/biz.go b/app/service/demo/internal/biz/biz.go new file mode 100644 index 0000000..f1be24d --- /dev/null +++ b/app/service/demo/internal/biz/biz.go @@ -0,0 +1,6 @@ +package biz + +import "github.com/google/wire" + +// ProviderSet is biz providers. +var ProviderSet = wire.NewSet(NewDemoUseCase) diff --git a/app/service/demo/internal/biz/demo.go b/app/service/demo/internal/biz/demo.go new file mode 100644 index 0000000..c1d7057 --- /dev/null +++ b/app/service/demo/internal/biz/demo.go @@ -0,0 +1,78 @@ +package biz + +import ( + "context" + "github.com/go-kratos/kratos/v2/log" + "gokratos-base/app/service/demo/internal/model" +) + +// DemoRepo is a Greater repo. +type DemoRepo interface { + Save(ctx context.Context, m *model.Demo) error + Update(ctx context.Context, m *model.Demo) error + GetByID(ctx context.Context, id int) (res *model.Demo, err error) + List(ctx context.Context, limit, offset int) (res []*model.Demo, err error) + DeleteByID(ctx context.Context, id int) (err error) +} + +// DemoUseCase is a Demo useCase. +type DemoUseCase struct { + repo DemoRepo + log *log.Helper +} + +type ListReq struct { + Page int + Size int +} + +// NewDemoUseCase new a Demo useCase. +func NewDemoUseCase(repo DemoRepo) *DemoUseCase { + return &DemoUseCase{ + repo: repo, + log: log.NewHelper(log.GetLogger()), + } +} + +// CreateDemo creates a Demo, and returns the new Demo. +func (uc *DemoUseCase) CreateDemo(ctx context.Context, m *model.Demo) error { + return uc.repo.Save(ctx, m) +} + +func (uc *DemoUseCase) UpdateDemo(ctx context.Context, m *model.Demo) error { + return uc.repo.Update(ctx, m) +} + +func (uc *DemoUseCase) GetDemo(ctx context.Context, id int) (*model.Demo, error) { + uc.log.WithContext(ctx).Info("qqqqqqqqqqqqqqqq") + + m, err := uc.repo.GetByID(ctx, id) + if err != nil { + return nil, err + } + + return m, nil + +} + +func (uc *DemoUseCase) ListDemo(ctx context.Context, req *ListReq) ([]*model.Demo, error) { + if req.Page <= 0 { + req.Page = 1 + } + + if req.Size <= 0 { + req.Size = 20 + } + + if req.Size >= 100 { + req.Size = 100 + } + + offset := (req.Page - 1) * req.Size + + return uc.repo.List(ctx, req.Size, offset) +} + +func (uc *DemoUseCase) DeleteDemo(ctx context.Context, id int) error { + return uc.repo.DeleteByID(ctx, int(id)) +} diff --git a/app/service/demo/internal/conf/conf.go b/app/service/demo/internal/conf/conf.go new file mode 100644 index 0000000..3402bad --- /dev/null +++ b/app/service/demo/internal/conf/conf.go @@ -0,0 +1,56 @@ +package conf + +import ( + "flag" + "gokratos-base/common/conf" + "gokratos-base/common/logz" + "gokratos-base/common/mysql" + "gokratos-base/common/redis" +) + +var ( + confPath string + Conf = &Config{} +) + +func init() { + flag.StringVar(&confPath, "conf", "config/config.yaml", "指定配置文件 eg: -conf config.yaml") +} + +type Config struct { + Server *Server + Data *Data + Log *logz.Config + Consul *Consul + Jaeger *Jaeger +} + +type Consul struct { + Addr string +} + +type Jaeger struct { + Url string +} + +type Data struct { + Mysql *mysql.Config + Redis *redis.Config +} + +type Server struct { + Name string + Version string + Grpc struct { + Addr string + Timeout int + } + Http struct { + Addr string + Timeout int + } +} + +func LoadConfig() { + conf.LoadFromYaml(confPath, &Conf) +} diff --git a/app/service/demo/internal/data/data.go b/app/service/demo/internal/data/data.go new file mode 100644 index 0000000..941c844 --- /dev/null +++ b/app/service/demo/internal/data/data.go @@ -0,0 +1,37 @@ +package data + +import ( + "github.com/go-kratos/kratos/v2/log" + "github.com/google/wire" + "gokratos-base/app/service/demo/internal/conf" + "gokratos-base/common/mysql" + "gokratos-base/common/redis" + "gorm.io/gorm" +) + +// ProviderSet is data providers. +var ProviderSet = wire.NewSet(NewData, NewDemoRepo) + +// Data . +type Data struct { + // TODO wrapped database client + DB *gorm.DB + Redis *redis.WrapClient +} + +// NewData . +func NewData(c *conf.Data) (*Data, func(), error) { + db := mysql.NewDB(c.Mysql) + rs := redis.NewRedis(c.Redis) + cleanup := func() { + d, _ := db.DB() + d.Close() + rs.Client.Close() + log.Debug("close data resources") + } + + return &Data{ + DB: db, + Redis: rs, + }, cleanup, nil +} diff --git a/app/service/demo/internal/data/demo.go b/app/service/demo/internal/data/demo.go new file mode 100644 index 0000000..8efd27b --- /dev/null +++ b/app/service/demo/internal/data/demo.go @@ -0,0 +1,52 @@ +package data + +import ( + "context" + "gokratos-base/app/service/demo/internal/biz" + "gokratos-base/app/service/demo/internal/model" + "time" +) + +type demoRepo struct { + data *Data +} + +var _ biz.DemoRepo = &demoRepo{} + +// NewDemoRepo . +func NewDemoRepo(data *Data) biz.DemoRepo { + return &demoRepo{ + data: data, + } +} + +func (r *demoRepo) Save(ctx context.Context, m *model.Demo) error { + err := r.data.DB.Model(&model.Demo{}).Create(m).Error + return err +} + +func (r *demoRepo) Update(ctx context.Context, m *model.Demo) error { + err := r.data.DB.Where("id = ?", m.Id).Updates(&model.Demo{ + Name: m.Name, + Value: m.Value, + UpdatedAt: int(time.Now().Unix()), + }).Error + return err +} + +func (r *demoRepo) GetByID(ctx context.Context, id int) (res *model.Demo, err error) { + res = &model.Demo{} + err = r.data.DB.Model(&model.Demo{}).Where("id = ?", id).Take(res).Error + return +} + +func (r *demoRepo) List(ctx context.Context, limit, offset int) (res []*model.Demo, err error) { + res = make([]*model.Demo, 0) + err = r.data.DB.Model(&model.Demo{}).Limit(limit).Offset(offset).Order("id desc").Find(&res).Error + return +} + +func (r *demoRepo) DeleteByID(ctx context.Context, id int) (err error) { + err = r.data.DB.Model(&model.Demo{}).Where("id = ?", id).Delete(&model.Demo{}).Error + return +} diff --git a/app/service/demo/internal/model/demo.go b/app/service/demo/internal/model/demo.go new file mode 100644 index 0000000..8079ce4 --- /dev/null +++ b/app/service/demo/internal/model/demo.go @@ -0,0 +1,13 @@ +package model + +type Demo struct { + Id int `json:"id"` // Id + Name string `json:"name"` // Name + Value string `json:"value"` // Value + CreatedAt int `json:"created_at"` // CreatedAt + UpdatedAt int `json:"updated_at"` // UpdatedAt +} + +func (d *Demo) TableName() string { + return "demo" +} diff --git a/app/service/demo/internal/server/grpc.go b/app/service/demo/internal/server/grpc.go new file mode 100644 index 0000000..eeba354 --- /dev/null +++ b/app/service/demo/internal/server/grpc.go @@ -0,0 +1,35 @@ +package server + +import ( + "github.com/go-kratos/kratos/v2/log" + "github.com/go-kratos/kratos/v2/middleware/recovery" + "github.com/go-kratos/kratos/v2/middleware/tracing" + "github.com/go-kratos/kratos/v2/transport/grpc" + "gokratos-base/api/service/demo" + "gokratos-base/app/service/demo/internal/conf" + "gokratos-base/app/service/demo/internal/service" + "time" +) + +// NewGRPCServer new a gRPC server. +func NewGRPCServer(c *conf.Server, svc *service.DemoService) *grpc.Server { + var opts = []grpc.ServerOption{ + grpc.Middleware( + recovery.Recovery(), + tracing.Server(), + ValidateParams(), + ), + } + if c.Grpc.Addr != "" { + opts = append(opts, grpc.Address(c.Grpc.Addr)) + } + if c.Grpc.Timeout != 0 { + opts = append(opts, grpc.Timeout(time.Duration(c.Grpc.Timeout)*time.Second)) + } + + srv := grpc.NewServer(opts...) + demo.RegisterDemoServer(srv, svc) + + logHelper = log.NewHelper(log.GetLogger()) + return srv +} diff --git a/app/service/demo/internal/server/http.go b/app/service/demo/internal/server/http.go new file mode 100644 index 0000000..1e6a529 --- /dev/null +++ b/app/service/demo/internal/server/http.go @@ -0,0 +1,39 @@ +package server + +import ( + "github.com/go-kratos/kratos/v2/middleware/auth/jwt" + "github.com/go-kratos/kratos/v2/middleware/recovery" + "github.com/go-kratos/kratos/v2/middleware/tracing" + "github.com/go-kratos/kratos/v2/transport/http" + jwtv4 "github.com/golang-jwt/jwt/v4" + "gokratos-base/api/service/demo" + "gokratos-base/app/service/demo/internal/conf" + "gokratos-base/app/service/demo/internal/service" + "gokratos-base/common/httpext" + "time" +) + +// NewHTTPServer new a http server. +func NewHTTPServer(c *conf.Server, svc *service.DemoService) *http.Server { + var opts = []http.ServerOption{ + http.Middleware( + recovery.Recovery(), + tracing.Server(), + jwt.Server(func(token *jwtv4.Token) (interface{}, error) { + return []byte("testkey"), nil + }), + ValidateParams(), + ), + http.ResponseEncoder(httpext.Encoder), + http.ErrorEncoder(httpext.ErrorEncoder), + } + if c.Http.Addr != "" { + opts = append(opts, http.Address(c.Http.Addr)) + } + if c.Http.Timeout != 0 { + opts = append(opts, http.Timeout(time.Duration(c.Grpc.Timeout)*time.Second)) + } + srv := http.NewServer(opts...) + demo.RegisterDemoHTTPServer(srv, svc) + return srv +} diff --git a/app/service/demo/internal/server/middleware.go b/app/service/demo/internal/server/middleware.go new file mode 100644 index 0000000..3bbb20a --- /dev/null +++ b/app/service/demo/internal/server/middleware.go @@ -0,0 +1,25 @@ +package server + +import ( + "context" + "github.com/go-kratos/kratos/v2/middleware" + "github.com/go-kratos/kratos/v2/transport" + "gokratos-base/common/errm" + "gokratos-base/common/validate" +) + +// ValidateParams 验证参数 +func ValidateParams() middleware.Middleware { + return func(handler middleware.Handler) middleware.Handler { + return func(ctx context.Context, req interface{}) (interface{}, error) { + if tr, ok := transport.FromServerContext(ctx); ok { + err := validate.Struct(req) + if err != nil { + logHelper.WithContext(ctx).Warnf("[%s]参数验证失败: %s", tr.Operation(), err.Error()) + return nil, errm.ParamsError(err.Error()) + } + } + return handler(ctx, req) + } + } +} diff --git a/app/service/demo/internal/server/server.go b/app/service/demo/internal/server/server.go new file mode 100644 index 0000000..cb1e13c --- /dev/null +++ b/app/service/demo/internal/server/server.go @@ -0,0 +1,12 @@ +package server + +import ( + "github.com/go-kratos/kratos/v2/log" + "github.com/google/wire" +) + +// ProviderSet is server providers. +var ( + ProviderSet = wire.NewSet(NewHTTPServer, NewGRPCServer) + logHelper *log.Helper +) diff --git a/app/service/demo/internal/service/convert.go b/app/service/demo/internal/service/convert.go new file mode 100644 index 0000000..7dafd5d --- /dev/null +++ b/app/service/demo/internal/service/convert.go @@ -0,0 +1,16 @@ +package service + +import ( + "gokratos-base/api/service/demo" + "gokratos-base/app/service/demo/internal/model" +) + +func DemoModelToRep(m *model.Demo) *demo.DemoModel { + return &demo.DemoModel{ + Id: int64(m.Id), + Name: m.Name, + Value: m.Value, + CreatedAt: int64(m.CreatedAt), + UpdatedAt: int64(m.UpdatedAt), + } +} diff --git a/app/service/demo/internal/service/demo.go b/app/service/demo/internal/service/demo.go new file mode 100644 index 0000000..0dd1b53 --- /dev/null +++ b/app/service/demo/internal/service/demo.go @@ -0,0 +1,77 @@ +package service + +import ( + "context" + "gokratos-base/api/service/demo" + "gokratos-base/app/service/demo/internal/biz" + "gokratos-base/app/service/demo/internal/model" +) + +// DemoService is a demo service. +type DemoService struct { + demo.UnimplementedDemoServer + uc *biz.DemoUseCase +} + +var _ demo.DemoServer = &DemoService{} + +// NewDemoService new a demo service. +func NewDemoService(uc *biz.DemoUseCase) *DemoService { + return &DemoService{uc: uc} +} + +// Hello implements DemoServer. +func (s *DemoService) Hello(ctx context.Context, req *demo.HelloReq) (*demo.HelloRep, error) { + return &demo.HelloRep{Message: "Hello " + req.Name}, nil +} +func (s *DemoService) Create(ctx context.Context, req *demo.CreateReq) (*demo.OKRep, error) { + err := s.uc.CreateDemo(ctx, &model.Demo{Name: req.Name, Value: req.Value}) + if err != nil { + return nil, err + } + return nil, nil +} + +func (s *DemoService) Update(ctx context.Context, req *demo.UpdateReq) (*demo.OKRep, error) { + err := s.uc.UpdateDemo(ctx, &model.Demo{Id: int(req.Id), Name: req.Name, Value: req.Value}) + if err != nil { + return nil, err + } + return &demo.OKRep{}, nil + +} + +func (s *DemoService) Get(ctx context.Context, req *demo.IdReq) (*demo.DemoModel, error) { + res, err := s.uc.GetDemo(ctx, int(req.Id)) + if err != nil { + return nil, err + } + return DemoModelToRep(res), nil +} + +func (s *DemoService) List(ctx context.Context, req *demo.ListReq) (*demo.ListRep, error) { + list, err := s.uc.ListDemo(ctx, &biz.ListReq{ + Page: int(req.Page), + Size: int(req.Size), + }) + + if err != nil { + return nil, err + } + + rep := &demo.ListRep{} + rep.List = make([]*demo.DemoModel, 0, len(list)) + + for _, v := range list { + rep.List = append(rep.List, DemoModelToRep(v)) + } + return rep, nil +} + +func (s *DemoService) Delete(ctx context.Context, req *demo.IdReq) (*demo.OKRep, error) { + err := s.uc.DeleteDemo(ctx, int(req.Id)) + if err != nil { + return nil, err + } + return &demo.OKRep{}, nil +} diff --git a/app/service/demo/internal/service/service.go b/app/service/demo/internal/service/service.go new file mode 100644 index 0000000..eadcc54 --- /dev/null +++ b/app/service/demo/internal/service/service.go @@ -0,0 +1,6 @@ +package service + +import "github.com/google/wire" + +// ProviderSet is service providers. +var ProviderSet = wire.NewSet(NewDemoService) diff --git a/app/service/demo/openapi.yaml b/app/service/demo/openapi.yaml new file mode 100644 index 0000000..6867057 --- /dev/null +++ b/app/service/demo/openapi.yaml @@ -0,0 +1,39 @@ +# Generated with protoc-gen-openapi +# https://github.com/google/gnostic/tree/master/cmd/protoc-gen-openapi + +openapi: 3.0.3 +info: + title: Greeter API + description: The greeting service definition. + version: 0.0.1 +paths: + /helloworld/{name}: + get: + tags: + - Greeter + - subgroup + description: Sends a greeting + operationId: Greeter_SayHello + parameters: + - name: name + in: path + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/helloworld.v1.HelloReply' +components: + schemas: + helloworld.v1.HelloReply: + type: object + properties: + message: + type: string + description: The response message containing the greetings +tags: + - name: Greeter -- 2.22.0