Reference address: https://go-zero.dev/cn/docs/quick-start/micro-service#%E5%88%9B%E5%BB%BAuser-rpc%E6%9C%8D%E5%8A%A1
Introduction to go-zero
go-zero (included in the CNCF Cloud Native Landscape: https://landscape.cncf.io/?selected=go-zero) is a web and rpc framework that integrates a variety of engineering practices. Through resilient design it guarantees the stability of highly concurrent server-side services and has been fully proven in practice.
go-zero includes a minimalist API definition and the generation tool goctl, which can generate Go, iOS, Android, Kotlin, Dart, TypeScript and JavaScript code from a defined api file with a single command, and the generated code can be run directly.
The benefits of using go-zero:
- Easily obtain the stability to support a service with tens of millions of daily active users
- Built-in microservice governance capabilities such as cascading timeout control, rate limiting, adaptive circuit breaking and adaptive load shedding, with no configuration or extra code required
- Microservice governance middleware can be seamlessly integrated into other existing frameworks
- A minimalist API description that generates code for every client with one command
- Automatically validates the legality of client request parameters
- A large number of microservice governance and concurrency toolkits
Quickly create a microservice according to the official documentation
We first create go-zero-demo in the go project directorymkdir go-zero-demo
cd go-zero-demo
go mod init go-zero-demoCreate the user rpc service
2.1 Create the user rpc directory
mkdir -p mall/user/rpc
2.2 Add the user.proto file and add a getUser method
vim mall/user/rpc/user.proto
2.3 Add the following code:
syntax = "proto3";
package user;
// for protoc-gen-go versions greater than 1.4.0, the proto file needs go_package, otherwise it cannot be generated
option go_package = "./user";
message IdRequest {
string id = 1;
}
message UserResponse {
// user id
string id = 1;
// user name
string name = 2;
// user gender
string gender = 3;
}
service User {
rpc getUser(IdRequest) returns(UserResponse);
}
2.4 Generate the code
cd mall/user/rpc
goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.

2.5 Fill in the business logic
vim internal/logic/getuserlogic.go
package logic
import (
"context"
"go-zero-demo/mall/user/rpc/internal/svc"
"go-zero-demo/mall/user/rpc/types/user"
"github.com/zeromicro/go-zero/core/logx"
)
type GetUserLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewGetUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserLogic {
return &GetUserLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *GetUserLogic) GetUser(in *user.IdRequest) (*user.UserResponse, error) {
return &user.UserResponse{
Id: "1",
Name: "test",
}, nil
}
- Create the order api service#
3.1 Create the order api directory
Go back to the go-zero-demo/mall directory
mkdir -p order/api && cd order/api
3.1 Add the api file
vim order.api
type(
OrderReq {
Id string `path:"id"`
}
OrderReply {
Id string `json:"id"`
Name string `json:"name"`
}
)
service order {
@handler getOrder
get /api/order/get/:id (OrderReq) returns (OrderReply)
}
3.2 Generate the order service
goctl api go -api order.api -dir .

3.3 Add the user rpc configuration
vim internal/config/config.go
Additional content
package config
import (
"github.com/zeromicro/go-zero/zrpc"
"github.com/zeromicro/go-zero/rest"
)
type Config struct {
rest.RestConf
UserRpc zrpc.RpcClientConf
}
3.4 Add the yaml configuration
vim etc/order.yaml
Name: order
Host: 0.0.0.0
Port: 8888
UserRpc:
Etcd:
Hosts:
- 127.0.0.1:2379
Key: user.rpc
3.5 Complete the service dependency
The official documentation uses user here, but when I used it locally I found that the generated code has no user, only userclient — it is very likely that the official documentation was not updated in time.
vim internal/svc/servicecontext.go
Additional content
package svc
import (
"go-zero-demo/mall/order/api/internal/config"
"go-zero-demo/mall/user/rpc/userclient"
"github.com/zeromicro/go-zero/zrpc"
)
type ServiceContext struct {
Config config.Config
UserRpc userclient.User
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
}
}
3.6 Add business logic to getorderlogic
vim internal/logic/getorderlogic.go
Additional content
package logic
import (
"context"
"errors"
"go-zero-demo/mall/order/api/internal/svc"
"go-zero-demo/mall/order/api/internal/types"
"go-zero-demo/mall/user/rpc/types/user"
"github.com/zeromicro/go-zero/core/logx"
)
type GetOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) GetOrderLogic {
return GetOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetOrderLogic) GetOrder(req *types.OrderReq) (*types.OrderReply, error) {
user, err := l.svcCtx.UserRpc.GetUser(l.ctx, &user.IdRequest{
Id: "1",
})
if err != nil {
return nil, err
}
if user.Name != "test" {
return nil, errors.New("用户不存在")
}
return &types.OrderReply{
Id: req.Id,
Name: "test order",
}, nil
}
- Start the services and verify#
4.1 Start etcd
There is no etcd service here, you need to install it yourself
etcd
4.2 Download the dependencies
In the go-zero-demo directory
go mod tidy
4.3 Start the user rpc
In the mall/user/rpc directory
go run user.go -f etc/user.yaml
If the following error appears, it means etcd has not been started
4.4 Start the order api
In the mall/order/api directory
go run order.go -f etc/order.yaml

4.5 Access the order api
curl -i -X GET http://localhost:8888/api/order/get/1


