Learn some more advanced tips and tricks for using gRPC with Fiddler Everywhere, including how to benefit from making the gRPC calls human-readable.
Is gRPC all about performance? Or is it gaining so much popularity because it is efficient, cross-platform, multi-language, interoperable, with a small footprint and, of course, secure? How does Progress Telerik Fiddler Everywhere fit, and what exactly is the “human readable gRPC call” part? I’m not sure if starting a blog post with so many questions is a good idea, but I can tell you that finishing a blog post with providing all the answers is.
Image source: Unsplash
First things first though, let’s do a quick intro on the main players today. gRPC (Google Remote Procedure Calls) is a modern open-source framework or—even better—architectural style that is highly suitable for building fast, scalable and language-agnostic microservices with strict contracts and real-time communication capabilities. It’s based on HTTP/2 and is a top choice for cloud-native applications, low-latency networks and systems requiring efficient data serialization.
Fiddler Everywhere is a web-debugging tool that captures, inspects, edits, filters and logs traffic (be it HTTPS, WebSocket, Server-Sent Events, Socket.IO or—of course—gRPC), issues requests between a machine (including mobile) and the internet, and fiddles with incoming and outgoing data. With it, you can compose API requests and share network debugging logs. It is cross-platform, human-readable and friendly (pun intended) and brings in high performance.
If you are a fan of quick five-minute videos explaining how everything works, I’ve got you covered as this video about gRPC is exactly for you, accompanied by a link to their official documentation. As a good beginner’s guide on how to get started with gRPC and Fiddler Everywhere, I’d recommend this blog post: Introduction to gRPC with Fiddler Everywhere, and of course the official Fiddler Everywhere documentation.
Image source: Unsplash
The purpose of the current blog post, however, is to take you one step further and unveil some more tips and tricks. Its main topic will focus on how to benefit from making the gRPC calls human-readable.
Unlike HTTP API requests, which can be created and read by humans, because they are sent as text, gRPC is not human-readable by default.
A major factor behind gRPC’s exceptional performance is its use of Protobuf for serialization. It is a binary protocol that’s not human-readable. On one hand, this significantly accelerates the remote procedure calls operations, but it can also complicate manual interactions with the server. Protobuf requires the message’s interface description specified in the .proto file to properly deserialize.
I can’t hide that I am a superheroes franchises fan, so let’s explore the difference between human-readable and Protobuf binary formats with such an example!
message Superhero {
optional string name = 1;
optional string superpower = 2;
optional string favorite_food = 3;
optional string sidekick_name = 4;
}
Based on the data structure above, here is my data instance:
{
"name": "Someone that had a close encounter with a spider",
"superpower": "Ability to cling to solid surfaces",
"favorite_food": "Aunt's Cherry Pie",
"sidekick_name": "They are so many"
}
Although still a mystery (right?), in this JSON format, it’s easy to see the superhero’s identity and abilities in a clear, human-readable form. Anyone can immediately understand the details about this superhero’s life, powers and food preferences as the key-value pairs are clearly displayed.
When serialized using Protobuf, this same data might look something like this in hex:
0a 2e 53 6f 6d 65 6f 6e 65 20 74 68 61 74 20 68 61 64 20 61 20 63 6c 6f 73 65 20 65 6e 63 6f 75 6e 74 65 72 20 77 69 74 68 20 61 20 73 70 69 64 65 72 12 23 41 62 69 6c 69 74 79 20 74 6f 20 63 6c 69 6e 67 20 74 6f 20 73 6f 6c 69 64 20 73 75 72 66 61 63 65 73 1a 10 41 75 6e 74 27 73 20 43 68 65 72 72 79 20 50 69 65 22 0e 54 68 65 79 20 61 72 65 20 73 6f 20 6d 61 6e 79
This is the exact same superhero information but serialized in Protobuf’s binary format. It’s efficient and compact, but completely unreadable to the naked eye. Without decoding, you would have no idea that this represents someone with a spider-related backstory who enjoys Aunt’s Cherry Pie!
While listing Protobuf’s binary format advantages like compact data storage, quick parsing, cross-language and cross-project compatibility, along with being forward-compatible, the lack of human-readable structure means you need tools or code to decode and interpret the data. In contrast, JSON or XML formats trade off performance for better readability, making them more suitable when human inspection is required.
This can create a challenge when trying to inspect gRPC traffic for debugging, testing or logging purposes. If you’re capturing gRPC calls with a traditional network analyzer, you’ll typically see unreadable binary blobs, making it difficult to verify the contents of requests and responses.
One of the common hurdles developers face when working with gRPC is monitoring and debugging its binary-encoded data. Tools like Fiddler Everywhere that support HTTP/2 can provide a solution to this because they are capable of parsing and displaying gRPC traffic in a human-readable format. As a side note, you can also use gRPC with “transcoded” mode over HTTP/1.
For the sake of this blog post, I have created a gRPC client and server in ASP.NET Core using Visual Studio 2022 and .NET 8. In my gRPC service project files, the Protos/greet.proto file looks like this:
syntax = "proto3";
option csharp_namespace = "GrpcGreeter";
package greet;
service Greeter {
rpc SayHello (HelloRequest) returns (Superhero);
}
message HelloRequest {
string name = 1;
}
message Superhero {
optional string name = 1;
optional string superpower = 2;
optional string favorite_food = 3;
optional string sidekick_name = 4;
}
My gRPC client is a .NET Console app and its Protos/greet.proto file looks like this:
syntax = "proto3";
option csharp_namespace = "GrpcGreeterClient";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (Superhero);
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message Superhero {
optional string name = 1;
optional string superpower = 2;
optional string favorite_food = 3;
optional string sidekick_name = 4;
}
Upon successful run, I get the following in the command prompt:
In Fiddler Everywhere, you need to set up the client using the gRPC framework to go through the Fiddler proxy. This condition depends on the different types of clients used.
This can be tricky, especially if you are using .NET, like in my project. If so, you need to know about a specific case in gRPC that prevents a gRPC channel from using the proxy settings. A possible solution to this would be to replace the default socket handler with the HttpHandler (which disables/removes some of the original logic and takes care of the proxy settings usage). This is valid not only for Fiddler but any proxy.
Without this workaround, whenever you run the client with a proxy on, you would get an error like “HttpRequestException: Unable to get subchannel from HttpRequestMessage.” I am calling it a workaround because a member of the grpc-dotnet team suggested in one of the threads that HttpClientHandler should be used when a proxy stands in the middle. You can read more about it here and here.
After adding the following to the Client Program.cs file, all should be fine and Fiddler Everywhere is ready to capture my superhero gRPC.
// using var channel = GrpcChannel.ForAddress(URL);
var URL = ;
// recreate the gRPC channel while using HttpClientHandler (to remove the default handler)
using var channel = GrpcChannel.ForAddress(
URL,
new GrpcChannelOptions
{
HttpHandler = new HttpClientHandler()
});
var client = new Greeter.GreeterClient(channel);
The captured gRPC session shows a green badge until the gRPC channel is open and a red badge when the gRPC channel is closed.
Double-click on a gRPC session to open the Messages tab and the Message inspector to inspect each gRPC message as originally received (the context menu provides decoding option) or through the HEX inspector. The Messages tab lists the outgoing (Sender: Client) and incoming (Sender: Server) gRPC messages. You can see the size and the original content of each message.
The Messages tab lists the outgoing (Sender: Client) and incoming (Sender: Server) gRPC messages. You can see the size and the original content of each message.
The raw Protobuf content that is captured can be partially visualized in text via the Decode value and HEX inspector. The fun starts, however, once you have the .proto file (owned by the scheme creator) with it you can get the decoded values of the message fields.
Provide the .proto file through the Settings > Protobuf > Decode via .proto file field. Like that, the gRPC message will have a tooltip indicating that Fiddler used a Protobuf file for its decoding. Here it is how it looks on my end.
Alternatively, the received gRPC messages will be automatically decoded if server reflection is available. Fiddler Everywhere detects out of the box if the gRPC server supports and uses server reflection. Note that the server reflection might not work when it uses TLS due to certificate errors. You can ignore the errors through the Settings > HTTPS > Ignore Server Certificate Errors option.
As gRPC continues to gain traction, the need for effective debugging and inspection tools has never been greater. Fiddler Everywhere steps in as a versatile, cross-platform solution that enables developers to make gRPC traffic human-readable, simplifying the process of debugging, monitoring and understanding gRPC interactions. Whether you’re troubleshooting complex service interactions or simply checking that your APIs are functioning as expected, you can focus more on building and maintaining reliable gRPC-based applications, and less on struggling with unreadable data.
Happy debugging!
Fiddler Everywhere comes with a free trial. Ready to give it a whirl?
Petar is a Principal Sales Engineer at Progress with equal sympathy in coding and automation testing. In his spare time he turns into a DIY guy who can successfully setup and use anything from IoT gadgets to paintbrushes and a trowel. When not dreaming of piloting the Millennium Falcon, he is a fan of any engine that is close enough and runs on two or four wheels.