hz client code generation
Introduction
Based on IDL, it generates RPC-like http requests code with a single click, which can block the tedious operation of creating and initializing hertz client and interoperate directly with the server code generated by hz.
This command needs to specify idl, otherwise no content will be generated.
The hz client command can be summarized by referring to hz client。
The code structure generated by the hz client can refer to hz client。
Generating code examples can refer to code 。
Example
This example is based on thrift, and protoc is similar to it.
Define IDL
The definition and semantics of the IDL are exactly the same as the current definition, so it is basically possible to generate client code without modifying the original IDL.
But for the client scenario, one annotation has been added, api.base_domain: specifies the default request domain to access.
Warn: When the api.any
annotation is used, the client automatically generates client code for the post
method to replace any
.
namespace go toutiao.middleware.hertz_client
struct FormReq {
1: string FormValue (api.form="form1"); // form annotation is used to declare the form parameter ("multipart/form-data")
}
struct QueryReq {
1: string QueryValue (api.query="query1"); // query annotation is used to declare the query parameters of the request
}
struct PathReq {
1: string PathValue (api.path="path1"); // path annotation is used to declare the routing parameters in the url
}
struct BodyReq {
1: string BodyValue (api.body="body"); // body annotation sets the entire structure to the body as a json, regardless of whether it is declared or not.
2: string QueryValue (api.query="query2");
}
struct Resp {
1: string Resp;
}
service HelloService {
// api.post is used to declare the route of the request
Resp FormMethod(1: FormReq request) (api.post="/form", api.handler_path="post");
Resp QueryMethod(1: QueryReq request) (api.get="/query", api.handler_path="get");
Resp PathMethod(1: PathReq request) (api.post="/path:path1", api.handler_path="post");
Resp BodyMethod(1: BodyReq request) (api.post="/body", api.handler_path="post");
}(
// api.base_domain is used to specify the default domain for client requests
api.base_domain="http://127.0.0.1:8888";
)
Generate client code
hz client --mod=a/b/c --idl=../idl/psm.thrift --model_dir=model --client_dir=hertz_client -t=template=slim
Advanced Settings
Client Option
Take the code generated by thrift IDL as an example
func main() {
generatedClient, err := hello_service.NewHelloServiceClient("https://www.example.com"),
hello_service.WithHertzClientOption() // Specify client configuration
}
Request-level configuration
Take the code generated by thrift IDL as an example
func main() {
generatedClient, err := hello_service.NewHelloServiceClient(
"http://toutiao.hertz.testa",
)
// The request level configuration can be specified when the call is initiated
resp, rawResp, err := generatedClient.QueryMethod(
context.Background(),
QueryReq,
config.WithSD(true), // Specify the request level setting to enable service discovery
config.WithReadTimeout(), // Specify the request read timeout
)
if err != nil {
fmt.Println(err)
return
}
}
Set client middleware
Take the code generated by thrift IDL as an example
func main() {
generatedClient, err := hello_service.NewHelloServiceClient(
"http://toutiao.hertz.testa",
hello_service.WithHertzClientMiddleware(), // Specify the client's middleware
)
}
Set global header
Take the code generated by thrift IDL as an example
There are some generic header that may need to be carried in every request, or some header that cannot be defined in IDL, then we can inject these header with “WithHeader” so that every request sent will carry these header.
func main() {
generatedClient, err := hello_service.NewHelloServiceClient(
"http://toutiao.hertz.testa",
hello_service.WithHeader(), // Specify the header that needs to be carried for each request sent
)
}
Configure TLS
Take the code generated by thrift IDL as an example
Hertz client’s TLS goes through the standard network library, so you need to configure it for the standard network library when using the generated one-click calls.
func main() {
generatedClient, err := hello_service.NewHelloServiceClient("https://www.example.com"),
hello_service.WithHertzClientOption(
client.WithDialer(standard.NewDialer()), // Use of standard libraries
client.WithTLSConfig(clientCfg), // TLS Configuration
)
}
Custom hertz client
Take the code generated by thrift IDL as an example
func main() {
generatedClient, err := hello_service.NewHelloServiceClient("https://www.example.com"),
hello_service.WithHertzClient() // Specify custom hertz client
}