Home / Blog / API Client
API ClientHow to Test gRPC Services and APIs

gRPC has become the default choice for high-throughput, low-latency communication between microservices. But its strengths - a binary wire format and a strict schema - are exactly what make it awkward to test with the tools you reach for with REST. You cannot just paste a URL into a browser and read JSON. This guide explains how gRPC works, what makes testing it different, and the practical tools and techniques engineers use to test gRPC services and APIs today.
A quick refresher: what makes gRPC different
gRPC is a remote procedure call (RPC) framework that runs over HTTP/2 and serializes messages with Protocol Buffers (protobuf). Instead of thinking in resources and URLs, you call typed methods on a service, almost like calling a local function. If you want a deeper conceptual primer, our explainer on what gRPC is and how it works covers the architecture in detail.
Three properties shape how you test it:
- Schema-first contracts. A
.protofile is the single source of truth for every method and message. Your tests are written against that contract. - Binary payloads. Messages are protobuf on the wire, not human-readable JSON, so you need tooling that can encode and decode against the schema.
- Four call types. gRPC supports unary (one request, one response), server streaming, client streaming, and bidirectional streaming. Streaming methods need different test strategies than simple unary calls.
A minimal service definition makes this concrete:
syntax = "proto3";
package user;
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc ListUsers (ListUsersRequest) returns (stream User); // server streaming
}
message GetUserRequest { string id = 1; }
message ListUsersRequest { int32 page_size = 1; }
message User {
string id = 1;
string name = 2;
string email = 3;
}
Server reflection: the key to easy gRPC testing
Because gRPC is binary, a client normally needs the .proto definitions to know how to talk to a server. Server reflection solves this: it is an optional gRPC service that lets a client ask the server, at runtime, which services and methods it exposes and what their messages look like.
When reflection is enabled, tools can discover and call methods with zero local files - a huge convenience for exploratory testing. When it is disabled (common in locked-down production), you point your tooling at the .proto files instead. Knowing which mode you are in is the first thing to establish.
Tools and techniques for testing gRPC
1. grpcurl - curl for gRPC
grpcurl is the command-line workhorse of gRPC testing. It speaks reflection, encodes your JSON input into protobuf, and prints the decoded response. Start by listing what the server offers:
# install (Go)
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
# list services exposed via server reflection
grpcurl example.com:443 list
# list methods on a service
grpcurl example.com:443 list user.UserService
# describe a message type
grpcurl example.com:443 describe user.User
Then call a method. You pass the request body as JSON and grpcurl handles the protobuf encoding for you. For server-streaming methods, each message prints as it arrives:
# unary call - pass the request as JSON, grpcurl encodes it to protobuf
grpcurl -d '{"id":"42"}' example.com:443 user.UserService/GetUser
# server-streaming call - each message prints as it arrives
grpcurl -d '{"page_size":50}' example.com:443 user.UserService/ListUsers
# when reflection is OFF, point grpcurl at the .proto files
grpcurl -import-path ./proto -proto user.proto \
-d '{"id":"42"}' example.com:443 user.UserService/GetUser
Authentication and TLS are handled with flags. Use -H to attach metadata such as a bearer token, and -plaintext for local servers that are not running TLS:
# send metadata (for example a bearer token) and use plaintext for local dev
grpcurl -plaintext \
-H 'authorization: Bearer eyJhbGciOi...' \
-d '{"id":"42"}' localhost:50051 user.UserService/GetUser
2. grpcui - a browser UI for exploration
grpcui wraps grpcurl in a local web interface. Run grpcui -plaintext localhost:50051 and it opens a form-based UI in your browser where you can pick a method, fill in fields, and see responses - handy for teammates who prefer clicking to typing flags.
3. Postman gRPC requests
Postman supports gRPC requests: you import a .proto file or use server reflection, select a method, compose the message, and invoke it, including streaming calls. It is a comfortable GUI if you already use Postman, though it is account- and cloud-oriented rather than local-first.
4. BloomRPC (legacy)
BloomRPC was a popular desktop GUI for gRPC, but the project is now archived and unmaintained. You will still see it referenced in older tutorials; for new work, grpcui or Postman are better-supported choices.
5. ghz - load testing gRPC
For performance work, ghz is the gRPC equivalent of classic HTTP load tools. It fires a configurable number of requests at a given concurrency and reports latency distributions and throughput:
# ghz: a load testing tool for gRPC (like hey/ab for gRPC)
ghz --insecure \
--proto ./proto/user.proto \
--call user.UserService.GetUser \
-d '{"id":"42"}' \
-c 50 -n 5000 \
localhost:50051
If you are planning broader performance work, see our guide to API load and performance testing for the concepts that apply across protocols.
6. Generated stubs - real automated tests
For repeatable integration tests in CI, generate client stubs from your .proto files and write tests in your own language. This gives you full type safety and lets you assert on streaming behaviour. A Go example for a unary method:
func TestGetUser(t *testing.T) {
conn, err := grpc.NewClient("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil { t.Fatal(err) }
defer conn.Close()
client := pb.NewUserServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
resp, err := client.GetUser(ctx, &pb.GetUserRequest{Id: "42"})
if err != nil { t.Fatalf("GetUser failed: %v", err) }
if resp.GetName() == "" { t.Error("expected a non-empty name") }
}
The same pattern applies in any language with protobuf support - generate the client, call the method, and assert on the typed response and the returned status code.
Testing streaming methods
Unary calls are easy: send one message, assert on one response. Streaming needs more thought:
- Server streaming: grpcurl prints each frame, but in automated tests you collect the stream into a slice and assert on its length, ordering, and contents.
- Client streaming: you send a sequence of messages and assert on the single summarized response - best done with generated stubs.
- Bidirectional streaming: the hardest case. You interleave sends and receives and verify the server’s ordering and timing. Always include a deadline so a stalled stream fails fast.
Whatever the call type, assert on the trailing status code (for example OK, NOT_FOUND, or UNAUTHENTICATED) - it is gRPC’s equivalent of an HTTP status and a common source of missed test coverage.
Where Requestly fits in
Requestly API Client is a Git-native desktop API client for REST, GraphQL, and SOAP, with collections, environments and variables, pre- and post-response scripting, and assertion-based tests - all running locally. Most gRPC systems also expose REST or GraphQL surfaces (gateways, admin endpoints, auth), and Requestly is an excellent home for those today.
Native gRPC support is on our roadmap and is not shipped yet. Until it arrives, the practical approach is grpcurl or grpcui for ad-hoc calls, ghz for load, and generated stubs for automated tests - while keeping your HTTP-based APIs in Requestly. For a conceptual comparison of the two styles, our gRPC vs REST explainer is a good next read.
Exploring other protocols and testing styles? See our companion guides on testing WebSocket APIs, load and performance testing, and setting up API monitoring, plus our roundup of the best API testing tools.
Try Requestly API Client: A Git-native desktop API client for REST, GraphQL, and SOAP - with collections, environments, scripting, and assertion-based tests that run entirely on your machine. Download Requestly →
Frequently asked questions
What is gRPC and how does it differ from REST?
gRPC is a high-performance RPC framework from Google that uses HTTP/2 for transport and Protocol Buffers for a strict, binary, schema-first contract. Where REST exposes resources over JSON and verbs, gRPC exposes typed methods you call like functions, supports streaming in both directions, and is generally faster and more compact - at the cost of being harder to inspect by hand.
What tools can I use to test gRPC services?
The most common tools are grpcurl (a command-line client like curl for gRPC), grpcui (a browser UI on top of grpcurl), Postman’s gRPC request type, and the now-archived BloomRPC. For load and integration testing, ghz is a popular choice. Generated client stubs from your .proto files also let you write tests in your own language.
What is gRPC server reflection and why does it matter for testing?
Server reflection is a gRPC service that lets a client ask the server which services and methods it exposes and what their message types look like, without having the .proto files on hand. When reflection is enabled, tools like grpcurl can list and call methods directly. When it is disabled, you must point your tooling at the .proto files instead.
How do I test a gRPC endpoint from the command line?
Install grpcurl, then list services with grpcurl example.com:443 list, and call a unary method by passing JSON: grpcurl -d '{"id":"42"}' example.com:443 user.UserService/GetUser. grpcurl converts your JSON to Protocol Buffers, sends it over HTTP/2, and prints the decoded response, making it the quickest way to smoke-test a service.
How do you test gRPC streaming methods?
gRPC supports unary, server-streaming, client-streaming, and bidirectional-streaming calls. For server streaming, grpcurl prints each message as it arrives. For client and bidirectional streaming you generally write tests against generated stubs so you can send a sequence of messages and assert on the ordered stream you receive back, including the final status code.
Does Requestly support gRPC testing?
Requestly is a local-first API client for REST, GraphQL, and SOAP today, with collections, environments, scripting, and tests. Native gRPC support is on our roadmap and not yet shipped. For gRPC work right now we recommend grpcurl or grpcui for quick calls and generated stubs for automated tests, while using Requestly for your HTTP-based APIs.
Test any API request visually: import a cURL command or build from scratch in Requestly, the free API client for developers.
Download Free →