GO111MODULE
is set to on
.This chapter gonna get you started with Kitex with a simple executable example.
First of all, let’s install compilers we gonna work with.
GOPATH
environment variable is defined properly (for example export GOPATH=~/go
), then add $GOPATH/bin
to PATH
environment variable (for example export PATH=$GOPATH/bin:$PATH
). Make sure GOPATH
is accessible.go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
go install github.com/cloudwego/thriftgo@latest
Now you can run kitex --version
and thriftgo --version
, and you can see some outputs just like below if you setup compilers successfully.
$ kitex --version
vx.x.x
$ thriftgo --version
thriftgo x.x.x
Tips: If you encounter any problem during installation, it’s probably you don’t setup golang develop environment properly. In most cases you can search error message to find solution.
git clone https://github.com/cloudwego/kitex-examples.git
enter hello
directory
cd kitex-examples/hello
run server
go run .
run client
open a another terminal, and go run ./client
enter the example directory
cd kitex-examples
build the example project
docker build -t kitex-examples .
run server
docker run --network host kitex-examples ./hello-server
run client
open another terminal, and docker run --network host kitex-examples ./hello-client
congratulation! You successfully use Kitex to complete a RPC.
open hello.thrift
, you will see code below:
namespace go api
struct Request {
1: string message
}
struct Response {
1: string message
}
service Hello {
Response echo(1: Request req)
}
Now let’s define a new request and responseAddRequest
和 AddResponse
, after that add add
method to service Hello
:
namespace go api
struct Request {
1: string message
}
struct Response {
1: string message
}
struct AddRequest {
1: i64 first
2: i64 second
}
struct AddResponse {
1: i64 sum
}
service Hello {
Response echo(1: Request req)
AddResponse add(1: AddRequest req)
}
When you complete it, hello.thrift
should be just like above.
Run below command, then kitex
compiler will recompile hello.thrift
and update generated code.
kitex -service a.b.c hello.thrift
# If the current directory is not under $GOPATH/src, you need to add the -module parameter which usually is same as the module name in go.mod
kitex -module "your_module_name" -service a.b.c hello.thrift
After you run the above command, kitex
compiler will update these files:
1. update `./handler.go`, add a basic implementation of `add` method.
2. update `./kitex_gen`, updates client and server implementation.
When you complete Regenerate Code chapter, kitex
will add a basic implementation of Add
to ./handler.go
, just like:
// Add implements the HelloImpl interface.
func (s *HelloImpl) Add(ctx context.Context, req *api.AddRequest) (resp *api.AddResponse, err error) {
// TODO: Your code here...
return
}
Let’s complete process logic, like:
// Add implements the HelloImpl interface.
func (s *HelloImpl) Add(ctx context.Context, req *api.AddRequest) (resp *api.AddResponse, err error) {
// TODO: Your code here...
resp = &api.AddResponse{Sum: req.First + req.Second}
return
}
Let’s add add
RPC to client example.
You can see something like below in ./client/main.go
:
for {
req := &api.Request{Message: "my request"}
resp, err := client.Echo(context.Background(), req)
if err != nil {
log.Fatal(err)
}
log.Println(resp)
time.Sleep(time.Second)
}
Let’s add add
RPC:
for {
req := &api.Request{Message: "my request"}
resp, err := client.Echo(context.Background(), req)
if err != nil {
log.Fatal(err)
}
log.Println(resp)
time.Sleep(time.Second)
addReq := &api.AddRequest{First: 512, Second: 512}
addResp, err := client.Add(context.Background(), addReq)
if err != nil {
log.Fatal(err)
}
log.Println(addResp)
time.Sleep(time.Second)
}
Shutdown server and client we have run, then:
run server
`go run .`
run client
open another terminal, and `go run ./client`
Now, you can see outputs of `add` RPC.
Kitex is a RPC framework which supports multiple serialization protocols and transport protocols.
Kitex compiler supports both thrift
and proto3
IDL, and fairly Kitex supports thrift
and protobuf
serialization protocol. Kitex extends thrift
as transport protocol, and also supports gRPC
protocol.
We use IDL to define interface.
Thrift IDL grammar: Thrift interface description language.
proto3 grammar: Language Guide(proto3).
Let’s create a directory to setup project.
$ mkdir example
enter directory
$ cd example
kitex
is a compiler which has the same name as Kitex
framework, it can generate a project including client and server conveniently.
You can use following command to install and upgrade kitex
:
$ go install github.com/cloudwego/kitex/tool/cmd/kitex
After that, you can just run it to check whether it’s installed successfully.
$ kitex
If you see some outputs like below, congratulation!
$ kitex
No IDL file found.
If you see something like command not found
, you should add $GOPATH/bin
to $PATH
. For detail, see chapter Prerequisites .
You can visit Compiler for detailed usage.
For example, a thrift IDL.
create a echo.thrift
file, and define a service like below:
namespace go api
struct Request {
1: string message
}
struct Response {
1: string message
}
service Echo {
Response echo(1: Request req)
}
We can use kitex
compiler to compile the IDL file to generate whole project.
$ kitex -module example -service example echo.thrift
-module
indicates go module name of project,-service
indicates expected to generate a executable service named example
, the last parameter is path to IDL file.
Generated project layout:
.
|-- build.sh
|-- echo.thrift
|-- handler.go
|-- kitex_gen
| `-- api
| |-- echo
| | |-- client.go
| | |-- echo.go
| | |-- invoker.go
| | `-- server.go
| |-- echo.go
| `-- k-echo.go
|-- main.go
`-- script
|-- bootstrap.sh
`-- settings.py
Kitex expect project to use go module as dependency manager. It cloud be easy to upgrade Kitex:
$ go get github.com/cloudwego/kitex@latest
$ go mod tidy
If you encounter something like below :
github.com/apache/thrift/lib/go/thrift: ambiguous import: found package github.com/apache/thrift/lib/go/thrift in multiple modules
Run following command, and try again:
go mod edit -droprequire=github.com/apache/thrift/lib/go/thrift
go mod edit -replace=github.com/apache/thrift=github.com/apache/thrift@v0.13.0
All method process entry should be in handler.go
, you should see something like below in this file:
package main
import (
"context"
"example/kitex_gen/api"
)
// EchoImpl implements the last service interface defined in the IDL.
type EchoImpl struct{}
// Echo implements the EchoImpl interface.
func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {
// TODO: Your code here...
return
}
Echo
method represents the echo
we defined in thrift IDL.
Now let’s make Echo
a real echo.
modify Echo
method:
func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {
return &api.Response{Message: req.Message}, nil
}
kitex compiler has generated scripts to compile and run the project:
Compile:
$ sh build.sh
There should be a output
directory After you execute above command, which includes compilation productions .
Run:
$ sh output/bootstrap.sh
Now, Echo
service is running!
Let’s write a client to call Echo
server.
create a directory as client package:
$ mkdir client
enter directory:
$ cd client
create a main.go
file.
Let’s new a client
to do RPC:
import "example/kitex_gen/api/echo"
import "github.com/cloudwego/kitex/client"
...
c, err := echo.NewClient("example", client.WithHostPorts("0.0.0.0:8888"))
if err != nil {
log.Fatal(err)
}
echo.NewClient
is used to new a client
, the first parameter is service name, the second parameter is options which is used to pass options. client.WithHostPorts
is used to specify server address, see chapter Basic Feature for details.
Let’s write call code:
import "example/kitex_gen/api"
...
req := &api.Request{Message: "my request"}
resp, err := c.Echo(context.Background(), req, callopt.WithRPCTimeout(3*time.Second))
if err != nil {
log.Fatal(err)
}
log.Println(resp)
We new a request req
, then we use c.Echo
to do a RPC call.
The first parameter context.Context
, is used to transfer information or to control some call behaviors. You will see detailed usage in behind chapters.\
The seconde parameter is request.
The third parameter is call options
, which is called callopt
, these options only works for this RPC call.
callopt.WithRPCTimeout
is used to specify timeout for this RPC call. See chapter Basic Feature for detail.
You can run following command to run a client:
$ go run main.go
You should see some outputs like below:
2021/05/20 16:51:35 Response({Message:my request})
Congratulation! You have written a Kitex server and client, and have done a RPC call.