go-nunu / nunu

A CLI tool for building Go applications.
https://go-nunu.github.io/nunu/
MIT License
1.9k stars 135 forks source link

有考虑加入rpc server 和 rpc client的模板和分层吗 #50

Open cpj555 opened 7 months ago

cpj555 commented 7 months ago

大佬模板整的挺好的,用这套搞了两应用,正好碰到用户体系的问题可能要拆点服务出去,不知道有没有现成的东西套下

codingcn commented 7 months ago

我先给个简单的例子参考着弄吧,不是很复杂。

提示:nunu-layout-micro这个以前写到一半搁置了,还没开源。

定义服务端

internal/server/grpc.go

package server

import (
    "fmt"
    "github.com/spf13/viper"
    "go.uber.org/zap"
    pb "nunu-layout-micro/api/user/v1"
    "nunu-layout-micro/internal/rpc"
    "nunu-layout-micro/pkg/log"
    "nunu-layout-micro/pkg/server/grpc"
)

func NewGRPCServer(
    logger *log.Logger,
    conf *viper.Viper,
    userServer rpc.UserServer,
) *grpc.Server {
    // 创建gRPC服务器
    s := grpc.NewServer(
        logger,
        grpc.WithServerHost(conf.GetString("grpc.host")),
        grpc.WithServerPort(conf.GetInt("grpc.port")),
    )
    logger.Info("grpc server start", zap.String("addr", fmt.Sprintf("%s:%d", conf.GetString("grpc.host"), conf.GetInt("grpc.port"))))

    // 注册GRPC服务
    pb.RegisterUserServiceServer(s, userServer)
    return s
}

internal/rpc/rpc.go

package rpc

import "nunu-layout-micro/pkg/log"

type RpcServer struct {
    logger *log.Logger
}

func NewRpcServer(logger *log.Logger) *RpcServer {
    return &RpcServer{
        logger: logger,
    }
}

internal/rpc/user.go

package rpc

import (
    "context"
    pb "nunu-layout-micro/api/user/v1"
    "nunu-layout-micro/internal/service"
)

type UserServer interface {
    Register(context.Context, *pb.RegisterRequest) (*pb.RegisterResponse, error)
    Login(context.Context, *pb.LoginRequest) (*pb.LoginResponse, error)
    UpdateProfile(context.Context, *pb.UpdateProfileRequest) (*pb.UpdateProfileResponse, error)
    GetProfile(context.Context, *pb.GetProfileRequest) (*pb.GetProfileResponse, error)
}

func NewUserServer(rpc *RpcServer, userService service.UserService) UserServer {
    return &userServer{
        userService: userService,
        RpcServer:   rpc,
    }
}

type userServer struct {
    userService service.UserService
    *RpcServer
}

func (s userServer) Register(ctx context.Context, request *pb.RegisterRequest) (*pb.RegisterResponse, error) {
    return s.userService.Register(ctx, request)
}

func (s userServer) Login(ctx context.Context, request *pb.LoginRequest) (*pb.LoginResponse, error) {
    return s.userService.Login(ctx, request)
}

func (s userServer) UpdateProfile(ctx context.Context, request *pb.UpdateProfileRequest) (*pb.UpdateProfileResponse, error) {
    //TODO implement me
    panic("implement me")
}

func (s userServer) GetProfile(ctx context.Context, request *pb.GetProfileRequest) (*pb.GetProfileResponse, error) {
    return s.userService.GetProfile(ctx, request)
}

定义客户端

internal/repository/repository.go

package repository

import (
    "context"
    polaris "github.com/polarismesh/grpc-go-polaris"
    "github.com/spf13/viper"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    pb "nunu-layout-micro/api/user/v1"
    "nunu-layout-micro/pkg/log"
)

type Repository struct {
    logger  *log.Logger
    userCli pb.UserServiceClient
}

func NewRepository(logger *log.Logger, userCli pb.UserServiceClient) *Repository {
    return &Repository{
        logger:  logger,
        userCli: userCli,
    }
}
func NewUserServiceClient(conf *viper.Viper, logger *log.Logger) (pb.UserServiceClient, func(), error) {
    // grpc客户端连接获取
    // 使用 grpc-go-polaris 提供的 DialContext 即可
        // polaris 是腾讯开源的一个服务治理框架,不使用它也可以,直接正常写原生grpc即可
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
    conn, err := polaris.DialContext(ctx, "polaris://QuickStartEchoServerGRPC",
        polaris.WithGRPCDialOptions(grpc.WithTransportCredentials(insecure.NewCredentials())),
        polaris.WithDisableRouter(),
    )
    if err != nil {
        logger.Sugar().Fatalf("Failed to dial gRPC service: %v", err)
    }
    return pb.NewUserServiceClient(conn), func() {
        cancel()
    }, nil
}

internal/repository/user.go

package repository

import (
    "context"
    pb "nunu-layout-micro/api/user/v1"
)

type UserRepository interface {
    Register(ctx context.Context, in *pb.RegisterRequest) (*pb.RegisterResponse, error)
    Login(ctx context.Context, in *pb.LoginRequest) (*pb.LoginResponse, error)
    UpdateProfile(ctx context.Context, in *pb.UpdateProfileRequest) (*pb.UpdateProfileResponse, error)
    GetProfile(ctx context.Context, in *pb.GetProfileRequest) (*pb.GetProfileResponse, error)
}

func NewUserRepository(r *Repository) UserRepository {
    return &userRepository{
        Repository: r,
    }
}

type userRepository struct {
    *Repository
}

func (u userRepository) Register(ctx context.Context, in *pb.RegisterRequest) (*pb.RegisterResponse, error) {
    return u.userCli.Register(ctx, in)
}

func (u userRepository) Login(ctx context.Context, in *pb.LoginRequest) (*pb.LoginResponse, error) {
    return u.userCli.Login(ctx, in)
}

func (u userRepository) UpdateProfile(ctx context.Context, in *pb.UpdateProfileRequest) (*pb.UpdateProfileResponse, error) {
    return u.userCli.UpdateProfile(ctx, in)
}

func (u userRepository) GetProfile(ctx context.Context, in *pb.GetProfileRequest) (*pb.GetProfileResponse, error) {
    return u.userCli.GetProfile(ctx, in)
}