I was recently chatting to Dan Clarke for the Unhandled Exception podcast, and the topic of testing gRPC endpoints came up. Dan wondered if there was an equivalent of Postman for gRPC, and it turns out that Postman itself supports gRPC!

However, when Dan tweeted about this finding, Laurent Kempé pointed out that this is also possible on Rider. As Rider is my daily-driver IDE, I was interested, but couldn't see immediately how to get started. In this post, I show how you can add the gRPC integration to Rider, and what that gives you!

As a sneak peak, here's Kahlid Abuhakmeh showing it off! We'll dig into this in more detail in the remainder of the post.

I'm not going to go into detail about how gRPC works, if you'd like an introductory blog post, there's a good one from Khalid here.

Getting started: create a gRPC sample app

The first thing you'll need to test out gRPC in Rider is a gRPC app! I used this sample application from my work on the Datadog APM tracer, but you can easily create a new ASP.NET Core gRPC application using dotnet new grpc or using the Visual Studio templates.

My sample app contains a .proto file, which defines the gRPC protocol buffers interface for the service. This file is shown below for completion sake, but any .proto file will do.

syntax = "proto3";

option csharp_namespace = "Samples.GrpcDotNet";

package greet.tester;

// The greeting service definition.
service Greeter {
  // Always throws
  rpc ErroringMethod (CreateErrorRequest) returns (HelloReply);

  // Unary call
  rpc Unary (HelloRequest) returns (HelloReply);

  // Hangs for 10s, so should exceed deadlines
  rpc VerySlow (HelloRequest) returns (HelloReply);

  // Server streaming
  rpc StreamingFromServer (HelloRequest) returns (stream HelloReply);

  // Client streaming
  rpc StreamingFromClient (stream HelloRequest) returns (HelloReply);

  // Client streaming
  rpc StreamingBothWays  (stream HelloRequest) returns (stream HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

message CreateErrorRequest {
  int32 errorType = 1;
}

Now you have a project, lets open it in Rider.

Installing the plugins

When you open the project in Rider, you won't initially get any gRPC prompts. If you open the .proto file, you'll see that the file doesn't have any syntax highlighting. However you should also get a prompt to install "Plugins supporting *.proto files":

Rider will suggest you install a plugin when you open a .proto file

If you click Install Plugins then it will suggest you install the Protocol Buffers plugin.

Rider will suggest you install the Protocol Buffers plugin

If you do this, you'll get syntax highlighting for the .proto file, but you won't get the full gRPC experience. Instead, we'll install a different plugin, cunningly called "gRPC".

Head to the plugins settings by navigating to File > Settings > Plugins > Marketplace and search for gRPC. Alternatively, use the ctrl+t shortcut and search for Plugins to be taken there directly. Install the gRPC plugin from the marketplace.

Install the gRPC plugin

With this installed, restart Rider and we'll look at what it gives you.

Using Rider's built-in client to send requests

After restarting your IDE, open up your .proto file, and you should see that it now has syntax highlighting, but that there are also some new symbols in the gutter, next to your endpoints:

The .proto file now has syntax highlighting and new symbols in the gutter

If you click one of these symbols, Rider creates an .http file for you, and starts populating it with the gRPC endpoint. These .http files can be used by Rider's built-in HTTP client to send test requests to your application. Think of it as a built-in Postman!

When Rider creates the endpoint in the .http file, it prompts you to enter the host.

Rider prompts you to enter your application's host

It defaults to some common options, but you'll need to modify this to whatever your local application uses. Start your app (we need it to be running to send requests to anyway!), and check which ports it says:

Hosting environment: Development
Content root path: C:\repos\Samples.GrpcDotNet
Now listening on: http://localhost:5002
Now listening on: https://localhost:7002
Application started. Press Ctrl+C to shut down.

So in my case I'm going to use port 5002. Note that you don't have to specify the scheme (http/https) in your gRPC .http files. Once you've updated the hostname, you can send a request! Click the green play symbol in the gutter, and Rider will send a gRPC request to your application

Send the request using the play symbol

The result is very slick—Rider records the response under the "Run" window, but it also records the response in a file right under the request. You can navigate to the file by ctrl+click on the link, or by hitting F12, and it shows the deserialized response:

{
  "message": "Hello "
}

It's also worth noting that you can include a body in your requests, and what's more, you get IntelliSense completion too:

You get IntelliSense completion for gRPC request bodys

The only requests I couldn't send were client-streaming requests, i.e. where I would need to stream multiple values. For example, see the /StreamingFromClient endpoint in the image at the start of this section. I can see why that's not supported, but it would be kinda nice to be able to provide multiple values that are all streamed. A feature request perhaps!

The generated-requests.http file created by Rider is stored as a "scratch" file by default. These are just temporary files that are shared across all solutions, but you could also include project-specific .http files in your repository if that makes sense!

The Endpoints window

If you have a lot of proto files in your project, then you might find it useful to take a look at the "Endpoints" tool window. This lists all the endpoints Rider knows about in your application. This includes ASP.NET Core APIs, OpenAPI specs, and gRPC endpoints (when you have the plugin installed).

The endpoints tool window includes gRPC endpoints

You can double-click or hit F12 on any of these endpoints and Rider will take you to its location in the .proto file, from where you can then generate a request. Unfortunately, the gRPC endpoints aren't supported in the inline "HTTP Client" window shown in the above image, so you can't send your test requests from there directly, you'll need to use the approach described in the previous section by creating a request from the gutter symbol in the .proto file. Another feature request then! 😃

Summary

In this post I showed how you can add improved gRPC support to JetBrains' Rider by installing the gRPC plugin. This enables syntax highlighting, endpoint discovery, and enables sending test requests using the built-in HTTP Client. The HTTP Client works very smoothly, saving requests for you to review later, and provides IntelliSense when crafting the request body. I'll definitely be using it when I need to test a gRPC service!