快速生成基于 go-zero+gorm+ddd 的商品服务 🚀

1,025 阅读2分钟

商品服务

生成基于 go-zero+gorm+ddd 的商品服务 demo

0.初始化

安装goctl protoc 工具, 生成gorm的模型需要替换goctl,版本分支 goctl138 github.com/tiptok/go-z…

1.建表

mkdir -p deploy/sql/product
touch deploy/sql/product/000001_create_product_table.up.sql

sql文件内容如下:

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    price DECIMAL(10, 2) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
		deleted_at timestamp       null,
    version    bigint       default 0
);
touch deploy/sql/product/000001_create_product_table.down.sql

sql文件内容如下:

drop table if exists product;

生成模型

goctl model mysql ddl -s deploy/sql/product/000001_create_product_table.up.sql -d app/product

2.编写proto文件

mkdir -p api/protobuf/product/v1
touch api/protobuf/product/v1/product.proto

proto文件如下:

syntax = "proto3";

package api.protobuf.product.v1;

option go_package = "../v1";

message Product {
  int64 id = 1;
  string name = 2;
  string description = 3;
  float price = 4;
  string unit = 5;
  int64 stock = 6;
  int64 created_at = 7;
  int64 updated_at = 8;
}

message CreateProductRequest {
  Product product = 1;
}

message CreateProductResponse {
  Product product = 1;
}

message UpdateProductRequest {
  Product product = 1;
}

message UpdateProductResponse {
  bool success = 1;
}

message GetProductRequest {
  int64 id = 1;
}

message GetProductResponse {
  Product product = 1;
}

message DeleteProductRequest {
  uint64 id = 1;
}

message DeleteProductResponse {
  bool success = 1;
}

message ListProductsRequest {
  int32 offset = 1;
  int32 limit = 2;
}

message ListProductsResponse {
  repeated Product products = 1;
  uint64 count = 2;
}

service ProductService {
  rpc GetProduct(GetProductRequest) returns (GetProductResponse) {}
  rpc CreateProduct(CreateProductRequest) returns (CreateProductResponse) {}
  rpc UpdateProduct(UpdateProductRequest) returns (UpdateProductResponse) {}
  rpc DeleteProduct(DeleteProductRequest) returns (DeleteProductResponse) {}
  rpc ListProducts(ListProductsRequest) returns (ListProductsResponse) {}
}

生成服务

goctl rpc protoc api/protobuf/product/v1/*.proto --go_out=./api/protobuf/product/v1 --go-grpc_out=./api/protobuf/product/v1 --zrpc_out=app/product/cmd/rpc

生成服务代码目录

product_project_layout.png

3.填写业务逻辑

初始化服务实例,配置多级缓存插件

func NewServiceContext(c config.Config) *ServiceContext {
   db := database.OpenGormDB(c.DB.DataSource)
   mlCache := cache.NewMultiLevelCache([]string{c.Redis.Host}, c.Redis.Pass)
   return &ServiceContext{
      Config:             c,
      DB:                 db,
      ProductsRepository: repository.NewProductsRepository(cache.NewCachedRepository(mlCache)),
   }
}

调用服务实例,开启事务创建产品添加到数据库表内

func (l *CreateProductLogic) CreateProduct(in *v1.CreateProductRequest) (*v1.CreateProductResponse, error) {
   product := &domain.Products{
      Name:        in.GetProduct().Name,
      Description: in.GetProduct().Description,
      Price:       in.GetProduct().Price,
      Unit:        in.GetProduct().Unit,
      Stock:       in.GetProduct().Stock,
   }

   var err error
   if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
      product, err = l.svcCtx.ProductsRepository.Insert(l.ctx, conn, product)
      return err
   }, true); err != nil {
      return nil, status.Errorf(codes.Internal, "failed to create product: %v", err)
   }
   return &v1.CreateProductResponse{
      Product: productservice.ProductEntityToProtobuf(product),
   }, nil
}

查询商品详情

func (l *GetProductLogic) GetProduct(in *v1.GetProductRequest) (*v1.GetProductResponse, error) {
   conn := l.svcCtx.DefaultDBConn()
   product, err := l.svcCtx.ProductsRepository.FindOne(l.ctx, conn, in.GetId())
   if err != nil {
      return nil, status.Error(codes.NotFound, fmt.Sprintf("not found product id %v", in.GetId()))
   }
   return &v1.GetProductResponse{
      Product: productservice.ProductEntityToProtobuf(product),
   }, nil
}

接口调用

create_product_request.png

get_product_request.png

go install github.com/fullstorydev/grpcui/cmd/grpcui@latest
grpcui -plaintext localhost:8080