fetch supports making gRPC calls with automatic protocol handling, JSON-to-protobuf conversion, and formatted responses.
gRPC (gRPC Remote Procedure Calls) is a high-performance RPC framework that uses Protocol Buffers for serialization and HTTP/2 for transport.
Enable gRPC mode. This flag:
- Forces HTTP/2 protocol
- Sets method to POST
- Adds gRPC headers (
Content-Type: application/grpc+proto,TE: trailers) - Applies gRPC message framing
- Handles gRPC response framing
fetch --grpc https://localhost:50051/package.Service/MethodThe service and method are specified in the URL path:
https://host:port/package.ServiceName/MethodName
Example:
# Call Echo method on EchoService in the echo package
fetch --grpc https://localhost:50051/echo.EchoService/EchoTo enable JSON-to-protobuf conversion and rich response formatting, provide a proto schema.
Compile .proto files using protoc (must be installed). Supports multiple comma-separated paths.
fetch --grpc --proto-file service.proto \
-j '{"message": "hello"}' \
https://localhost:50051/echo.EchoService/EchoMultiple files:
fetch --grpc --proto-file common.proto,service.proto \
-j '{"request": "data"}' \
https://localhost:50051/pkg.Service/MethodUse a pre-compiled descriptor set file. Useful when:
protocisn't available at runtime- You want faster startup (no compilation)
- Building CI/CD pipelines
Generate a descriptor set:
protoc --descriptor_set_out=service.pb --include_imports service.protoUse the descriptor:
fetch --grpc --proto-desc service.pb \
-j '{"message": "hello"}' \
https://localhost:50051/echo.EchoService/EchoAdd import paths for proto compilation. Use with --proto-file when your protos have imports.
fetch --grpc \
--proto-file service.proto \
--proto-import ./proto \
--proto-import /usr/local/include \
-j '{"field": "value"}' \
https://localhost:50051/pkg.Service/Method- The service and method are extracted from the URL path
fetchlooks up the method's input/output message types in the schema- JSON request bodies are converted to protobuf wire format
- The request is framed with gRPC length-prefix
- Response protobuf is formatted as JSON with field names from the schema
When no schema is provided:
- Request bodies must be raw protobuf (not JSON)
- Responses are formatted using generic protobuf parsing
- Field numbers are shown instead of names
With a proto schema, send JSON that matches your message structure:
fetch --grpc --proto-file user.proto \
-j '{
"name": "John Doe",
"age": 30,
"email": "john@example.com"
}' \
https://localhost:50051/users.UserService/CreateUserThe JSON is automatically converted to protobuf wire format.
fetch --grpc --proto-file order.proto \
-j '{
"customer": {
"id": 123,
"name": "Jane"
},
"items": [
{"product_id": 1, "quantity": 2},
{"product_id": 5, "quantity": 1}
]
}' \
https://localhost:50051/orders.OrderService/CreateOrderFor methods that take empty messages:
fetch --grpc --proto-file service.proto \
https://localhost:50051/health.HealthService/CheckOr with an empty JSON object:
fetch --grpc --proto-file service.proto \
-j '{}' \
https://localhost:50051/health.HealthService/Checkfetch --grpc --proto-file service.proto \
-j @request.json \
https://localhost:50051/pkg.Service/MethodResponses are formatted as JSON with field names:
{
"name": "John Doe",
"age": 30,
"email": "john@example.com",
"created_at": {
"seconds": 1704067200,
"nanos": 0
}
}Generic protobuf parsing shows field numbers:
1: "John Doe"
2: 30
3: "john@example.com"
4 {
1: 1704067200
2: 0
}
For development servers with self-signed certificates:
fetch --grpc --insecure \
--proto-file service.proto \
-j '{"request": "data"}' \
https://localhost:50051/pkg.Service/Methodfetch --grpc \
--ca-cert ca.crt \
--proto-file service.proto \
-j '{"request": "data"}' \
https://server.example.com:50051/pkg.Service/Methodfetch --grpc \
--cert client.crt \
--key client.key \
--ca-cert ca.crt \
--proto-file service.proto \
-j '{"request": "data"}' \
https://secure.example.com:50051/pkg.Service/MethodSee request and response headers:
fetch --grpc --proto-file service.proto \
-j '{"field": "value"}' \
-vv \
https://localhost:50051/pkg.Service/MethodInspect the request without sending:
fetch --grpc --proto-file service.proto \
-j '{"field": "value"}' \
--dry-run \
https://localhost:50051/pkg.Service/MethodModify the JSON request body in an editor:
fetch --grpc --proto-file service.proto \
-j '{"template": "value"}' \
--edit \
https://localhost:50051/pkg.Service/Methodfetch --grpc https://localhost:50051/grpc.health.v1.Health/Checkfetch --grpc --proto-file api.proto \
-j '{
"resource": {
"name": "my-resource",
"type": "TYPE_A",
"config": {"key": "value"}
}
}' \
https://api.example.com/resources.ResourceService/Createfetch --grpc --proto-file api.proto \
-j '{"page_size": 10, "page_token": ""}' \
https://api.example.com/users.UserService/ListUsersfetch --grpc --proto-file api.proto \
-H "Authorization: Bearer $TOKEN" \
-j '{"id": "123"}' \
https://api.example.com/users.UserService/GetUserInstall Protocol Buffers compiler:
# macOS
brew install protobuf
# Ubuntu/Debian
apt install protobuf-compiler
# Or use --proto-desc with pre-compiled descriptors- Verify the URL path matches
package.Service/Methodexactly - Check that your proto file defines the service and method
- Ensure all required imports are included via
--proto-import
- Verify JSON syntax is correct
- Check field names match proto definitions (use snake_case)
- Ensure types match (strings quoted, numbers not quoted)
- gRPC requires HTTP/2 - ensure server supports it
- Check port number (gRPC typically uses different ports than REST)
- For TLS issues, try
--insecurefor testing
- If response is empty, check gRPC status in headers (
-vv) - Verify proto schema matches server's actual message format
- Try without schema to see raw wire format
fetch supports server-side streaming gRPC responses. Each response message is formatted and displayed as it arrives, following the same real-time streaming pattern used for SSE and NDJSON responses.
fetch --grpc --proto-file service.proto \
-j '{"query": "search term"}' \
https://localhost:50051/search.SearchService/StreamResultsFor streaming responses, messages are separated by blank lines in the output. Formatting and flushing happen incrementally, so results appear in real time.
fetch reports gRPC status errors from response trailers. If the server returns a non-OK gRPC status (e.g., INTERNAL, NOT_FOUND), the error is printed to stderr and the exit code is set to 1.
fetch supports client-side streaming gRPC calls. When the proto schema indicates a method is client-streaming, multiple JSON objects in the request body are each converted to a separate protobuf message and sent as individual gRPC frames.
Detection is automatic via the method descriptor in the proto schema — no additional flags are needed.
Provide multiple JSON objects separated by whitespace:
fetch --grpc --proto-file service.proto \
-d '{"value":"one"}{"value":"two"}{"value":"three"}' \
https://localhost:50051/pkg.Service/ClientStreamfetch --grpc --proto-file service.proto \
-d @messages.ndjson \
https://localhost:50051/pkg.Service/ClientStreamPipe data from stdin for real-time streaming — each JSON object is sent as soon as it is parsed:
cat messages.ndjson | fetch --grpc --proto-file service.proto \
-d @- https://localhost:50051/pkg.Service/ClientStreamBidirectional streaming is supported with the same mechanism as client streaming. When piping from stdin, request frames are sent incrementally while response frames are received and displayed concurrently:
cat messages.ndjson | fetch --grpc --proto-file service.proto \
-d @- https://localhost:50051/pkg.Service/BidiStreamBoth directions flow on the same HTTP/2 stream. The response is formatted and displayed as messages arrive, just like server streaming.
- Client/bidi streaming requires a proto schema: The
--proto-fileor--proto-descflag must be provided sofetchcan detect that a method is client-streaming - gRPC-Web: Standard gRPC protocol only, not gRPC-Web
- CLI Reference - All gRPC options
- Authentication - mTLS setup
- Troubleshooting - Common issues