Closed LinuxSuRen closed 8 months ago
Hi, LinuxSuRen, I am glad to hear that. Contribution to tRPC ecosystem is highly welcome. Here is tRPC protocol ,Perhaps u can implement tRPC protocol and add it as the extenions of api-testing. Any question, U can leave a message here, we are glad to answer it asap.
hi @sandyskies , thanks for the quick response.
Below is the implement of gRPC
@LinuxSuRen can u implement tRPC protocol?
I'm not familiar with the tRPC, especially about how to send the request dynamically. So this will not be a short task for me.
@LinuxSuRen So the advantages of API Testing are supporting multiple protocols such as gRPC or other RPC?
I hope API Testing could support all popular API protocols. But it supports HTTP, gRPC for now.
It defined interface, and has two implements:
Anyone could help me to find an example about how to invoke a service method dynamically? Currently, I fond the code to parse the proto file. But I don't know how to form the req and resp for the Invoke method. Thanks for your time.
You may check this quick start. Checkout the implementation inside cmd/client/main.go
Or are you seeking some tool that can take a proto
file and some arguments as input to invoke a running service?
hi @WineChord , thanks for your reply. I find the parse method from that project. I'm trying to Unmarshal a data by the following code:
ser := restful.GetSerializer("application/json")
send := []byte{}
err = ser.Unmarshal([]byte(`{"name":"SuRen"}`), &send)
fmt.Println(err)
resp := []byte{}
err = c.Invoke(ctx, send, resp, callopts...)
fmt.Println(err)
but no process got for now.
Take a look at this function generated in stub code: https://github.com/trpc-group/trpc-go/blob/main/testdata/trpc/helloworld/helloworld.trpc.go#L109
For encoding a trpc frame, refer to https://github.com/trpc-group/trpc-go/blob/main/codec.go#L347
Do I miss something in the below:
ctx, msg := codec.WithNewMessage(ctx)
fh := &trpc.FrameHead{
StreamID: 2,
}
msg.WithFrameHead(fh)
defer codec.PutBackMessage(msg)
msg.WithClientRPCName("/trpc.helloworld.Greeter/Hello")
msg.WithCalleeServiceName(fd.Services[0].Name)
msg.WithCalleeApp("")
msg.WithCalleeServer("")
msg.WithCalleeService("Greeter")
msg.WithCalleeMethod("Hello")
msg.WithClientMetaData(codec.MetaData{"msg": make([]byte, 16)})
msg.WithSerializationType(codec.SerializationTypePB)
callopts := make([]client.Option, 0)
fmt.Println(callopts)
var req []byte
var resp []byte
cc := codec.GetClient(trpc.ProtocolName)
fmt.Println("cc", cc)
req, err = cc.Encode(msg, []byte(`{"msg":"hello"}`))
fmt.Println("encode", err)
resp, err = cc.Encode(msg, nil)
fmt.Println("encode resp", err)
err = c.Invoke(ctx, req, resp, callopts...)
fmt.Println("invoke", err)
The reqBody
parameter for Encode
should be serialized body, which is serialized according to msg.WithSerializationType
beforehand.
Something like:
req := &pb.HelloRequest{}
reqBody, _ := proto.Marshal(req)
reqBytes, err = cc.Encode(msg, reqBody)
In your case, the body you passed is {"msg":"hello"}
, which is of serialization type JSON, so you should use msg.WithSerializationType(codec.SerializationTypeJSON)
instead of msg.WithSerializationType(codec.SerializationTypePB)
.
The server received data, but got error invoke type:callee framework, code:1, msg:service codec Unmarshal: proto: syntax error (line 1:1): unexpected token
Can you provide your current server code and client code?
The server code https://github.com/trpc-group/trpc-go/blob/main/examples/helloworld/server/main.go
Below is the client:
c := client.New()
fmt.Println(c)
ctx := context.Background()
fmt.Println(ctx)
opts := []parser.Option{
parser.WithAliasOn(false),
parser.WithAPPName(""),
parser.WithServerName(""),
parser.WithAliasAsClientRPCName(false),
parser.WithLanguage("Go"),
parser.WithRPCOnly(true),
parser.WithMultiVersion(false),
}
fd, err := parser.Parse(
"/root/ws/LinuxSuRen/api-testing/dist/helloworld.proto",
[]string{},
0,
opts...,
)
if err != nil {
fmt.Println(err)
return
}
for _, a := range fd.Services {
fmt.Println(a.Name)
}
md := fd.Services[0].MethodRPC["Hello"]
fmt.Println("===", md.RequestType, md.RequestTypeFileOptions, md.RequestTypePkgDirective)
ctx, msg := codec.WithCloneMessage(ctx)
// fh := &trpc.FrameHead{
// StreamID: 2,
// }
fmt.Println("fd.Services[0].Name", md.RequestTypePkgDirective+"."+fd.Services[0].Name)
// msg.WithFrameHead(fh)
defer codec.PutBackMessage(msg)
msg.WithClientRPCName("/trpc.helloworld.Greeter/Hello")
msg.WithCalleeServiceName(md.RequestTypePkgDirective + "." + fd.Services[0].Name)
msg.WithCalleeApp("")
msg.WithCalleeServer("")
msg.WithCalleeService("Greeter")
msg.WithCalleeMethod("Hello")
// msg.WithClientMetaData(codec.MetaData{"msg": make([]byte, 16)})
// msg.WithSerializationType(codec.SerializationTypePB)
msg.WithSerializationType(codec.SerializationTypeJSON)
callopts := make([]client.Option, 0)
callopts = append(callopts, client.WithTarget("ip://127.0.0.1:8000"))
fmt.Println(callopts)
var req []byte
var resp []byte
cc := codec.GetClient(trpc.ProtocolName)
fmt.Println("cc", cc)
req, err = cc.Encode(msg, []byte(`{"msg":"hello"}`))
fmt.Println("encode", err)
respData := []byte(`{"msg":""}`)
resp, err = cc.Encode(msg, respData)
fmt.Println("encode resp", err)
err = c.Invoke(ctx, req, resp, callopts...)
fmt.Println("invoke", err)
Why not just use https://github.com/trpc-group/trpc-go/blob/main/examples/helloworld/client/main.go#L13?
c := pb.NewGreeterClientProxy(client.WithTarget("ip://127.0.0.1:8000"))
rsp, err := c.Hello(context.Background(), &pb.HelloRequest{Msg: "world"})
The parameters req,resp
in c.Invoke(ctx, req, resp, callopts...)
are not of type []byte
.
If you want to send raw bytes, you must refer to https://github.com/trpc-group/trpc-go/blob/main/docs/user_guide/reverse_proxy.md#specifying-the-empty-serialization-method-1. But I think this is not what you intent to do.
Again, please read the generated stub code more carefully.
Finally, I did it. I need to use the invoke
method instead of the stub code, because this is an API testing tool which need to load proto file then execute it dynamically. Thanks for your help.
Cool! You may consider updating the trpc docs to add a section on how to use api-testing to test trpc-go servers.
Sure. Will do it once I complete the unit tests of https://github.com/LinuxSuRen/api-testing/pull/254
hi the trpc team, I'm the maintainer of api-testing which aims to be an alternative solution to Postman. Instead of Postman,
api-testing
is totally open-source. And it has an extension (or plug-in) mechanism.Add more background of
api-testing
. It already supportsHTTP
andgRPC
protocols. For Docker users, you could simply type the following command to get started:The web server local address is
http://localhost:8080
.