Develop RPC Server & RPC Client

Dubbo-go Quick Start

Based on the Triple protocol defined by Dubbo, you can easily write browser and gRPC compatible RPC services that run on both HTTP/1 and HTTP/2 simultaneously. The Dubbo Go SDK supports defining services using IDL or programming language-specific methods and provides a lightweight API for publishing or invoking these services.

This example demonstrates the RPC communication pattern based on the Triple protocol. The example uses Protocol Buffer to define the RPC service and demonstrates the processes of code generation, service publishing, and service access.

Prerequisites

Since we are using Protocol Buffer, we first need to install the relevant code generation tools, including protoc, protoc-gen-go, and protoc-gen-go-triple.

  1. Install protoc

    Check the Protocol Buffer Compiler Installation Guide

  2. Install protoc plugins

    Next, we install the plugins protoc-gen-go and protoc-gen-go-triple.

    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    go install dubbo.apache.org/dubbo-go/v3/cmd/protoc-gen-go-triple@v3.0.1
    

    Make sure protoc-gen-go and protoc-gen-go-triple are in your PATH. You can verify this with which protoc-gen-go. If that command does not work, please execute the following commands:

    [ -n "$(go env GOBIN)" ] && export PATH="$(go env GOBIN):${PATH}"
    [ -n "$(go env GOPATH)" ] && export PATH="$(go env GOPATH)/bin:${PATH}"
    

Quick Run Example

Download Example Source Code

We maintain a series of dubbo-go usage examples in the apache/dubbo-go-samples repository to help users quickly learn how to use dubbo-go.

You can download the example zip file and unzip it, or clone the repository:

$ git clone --depth 1 https://github.com/apache/dubbo-go-samples

Switch to the quick start example directory:

$ cd dubbo-go-samples/helloworld

Run Server

In the go-server/cmd directory:

Run the following command to start the server:

$ go run server.go

Use cURL to verify that the server has been started correctly:

$ curl \
      --header "Content-Type: application/json" \
      --data '{"name": "Dubbo"}' \
      http://localhost:20000/greet.GreetService/Greet

Greeting: Hello world

Run Client

Open a new terminal and run the following command in the go-client/cmd directory to start the client:

$ go run client.go

Greeting: Hello world

This is a complete development process of a dubbo-go RPC communication service.

Source Code Explanation

Next, we will explain the source code of the dubbo-go-samples/helloworld example.

Define Service

The example uses Protocol Buffer (IDL) to define the Dubbo service.

syntax = "proto3";

package greet;
option go_package = "github.com/apache/dubbo-go-samples/helloworld/proto;greet";

message GreetRequest {
  string name = 1;
}

message GreetResponse {
  string greeting = 1;
}

service GreetService {
  rpc Greet(GreetRequest) returns (GreetResponse) {}
}

This file declares a service called GreetService, defining the Greet method along with its request parameter GreetRequest and return value GreetResponse.

Generate Code

Before running the server or client, we need to generate the relevant code using protoc-gen-go and protoc-gen-go-triple.

protoc --go_out=. --go_opt=paths=source_relative \
    --go-triple_out=. --go-triple_opt=paths=source_relative \
    ./greet.proto

After running the above command, you will see the following generated files in the target directory:

 proto
    ├── greet.pb.go
    ├── greet.proto
    └── greet.triple.go

In the proto/greet/v1 package, there are two parts:

  • greet.pb.go is generated by Google’s standard protoc-gen-go, which contains the structures of GreetRequest, GreetResponse, and the encoding/decoding rules.
  • greet.triple.go is produced by the custom Dubbo plugin protoc-gen-go-triple and includes key information, including the generated interface GreetService, constructors, and more.

Implement Service

Next, we need to add business logic by implementing the greet.GreetService interface.

type GreetTripleServer struct {
}

func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) {
	resp := &greet.GreetResponse{Greeting: req.Name}
	return resp, nil
}

Start Server

Create a new Server, register the GreetTripleServer we implemented earlier, and then initialize and start the Server, which will listen for requests on the specified port.

func main() {
	srv, err := server.NewServer(
		server.WithServerProtocol(
			protocol.WithPort(20000),
			protocol.WithTriple(),
		),
	)
	if err != nil {
		panic(err)
	}

	if err := greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); err != nil {
		panic(err)
	}

	if err := srv.Serve(); err != nil {
		logger.Error(err)
	}
}

Access Service

The simplest way is to use an HTTP/1.1 POST request to access the service, passing the parameters as standard JSON format in the HTTP payload. Here is an example using a cURL command:

curl \
    --header "Content-Type: application/json" \
    --data '{"name": "Dubbo"}' \
    http://localhost:20000/greet.GreetService/Greet

You can also use a Dubbo client to request the service. First, obtain the service proxy from the generated code in the greet package, specify the server address, and initialize it. Then you can initiate an RPC call.

func main() {
	cli, err := client.NewClient(
		client.WithClientURL("127.0.0.1:20000"),
	)
	if err != nil {
		panic(err)
	}

	svc, err := greet.NewGreetService(cli)
	if err != nil {
		panic(err)
	}

	resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"})
	if err != nil {
		logger.Error(err)
	}
	logger.Infof("Greet response: %s", resp.Greeting)
}

This is the basic working principle of dubbo-go RPC!

More Content

More Features of RPC Framework

Learn about Streaming communication models, configuring timeout durations, passing headers, and more framework configurations.

Governance capabilities such as service discovery

Learn how to use dubbo-go to develop microservices, incorporating service discovery, observability, traffic control, and more service governance capabilities.