protocols
gRPC requests
Call gRPC services from Cloak Proxy with server reflection or .proto files, all four call types, JSON messages, metadata, deadlines and status-based tests.
A gRPC request calls one method of a gRPC service. You write the request message as JSON, Cloak Proxy encodes it as Protocol Buffers using the service’s schema, and decodes every reply back to JSON. The schema comes from the server itself through server reflection, or from .proto files and descriptor sets you choose. Unary, server streaming, client streaming and bidirectional streaming calls are all supported.
Call a method
Section titled “Call a method”-
In the API client, click New › Other Protocols › gRPC, or right-click a collection and choose Add Other Request › gRPC. Search Everything (⇧ ⌘ A) also has New gRPC Request.
The new request points at a public test server,
grpcs://grpcb.in:9001. -
Type the server’s address in the URL bar, for example
grpcs://api.example.com:443orgrpc://localhost:50051. -
Load the schema:
- With Use server reflection checked (the default), click Load via Server Reflection.
- Otherwise uncheck it, click Choose .proto Files…, select your files, and click Load .proto Files.
The Messages log reports how many services were loaded, or Couldn’t load the schema with the reason.
-
Pick a method from the menu in the URL bar. It lists every method as
package.Service.Method · Call type. When the message editor is empty, Cloak Proxy fills it with an example message for the method’s input type. -
Edit the JSON in Message and add any metadata in Metadata.
-
Press ⌘ ↩ or click Invoke. Replies, headers and the final status appear in the Messages log.
A new gRPC request. Load the schema first, then pick a method.
- Server address
- Method menu, with each method's call type
- Invoke (⌘↩)
- Load the schema by reflection or from .proto files
- Message, Metadata and Settings tabs
- Messages log: every message, header and status
Server address
Section titled “Server address”The URL bar accepts these forms:
| You type | Connection |
|---|---|
grpcs://host:port or https://host:port |
TLS, with HTTP/2 negotiated through ALPN. |
grpc://host:port, http://host:port or h2c://host:port |
Plaintext HTTP/2 (h2c, prior knowledge), for local and internal servers. |
host:port |
TLS when the port is 443, plaintext otherwise. |
host |
TLS on port 443. |
[::1]:50051 |
IPv6 addresses in brackets. |
{{variables}} work in the address. gRPC calls connect straight to the server; they don’t go through Cloak Proxy’s listening port.
Load the schema
Section titled “Load the schema”Cloak Proxy needs the service definitions to encode and decode messages.
With Use server reflection checked, Load via Server Reflection asks the server for its services using the gRPC reflection protocol. Cloak Proxy tries grpc.reflection.v1 first and falls back to grpc.reflection.v1alpha. The log shows the services it found and the reflection version used.
The server must have reflection turned on. Many production servers don’t, in which case use .proto files.
Uncheck Use server reflection and click Choose .proto Files…. You can select several files at once:
| File type | Use |
|---|---|
.proto |
Protocol Buffers source. Select every file your service imports, too. Imports are matched to the selected files by path. |
.pb or .desc |
A compiled descriptor set, for example from protoc --descriptor_set_out=api.desc --include_imports. |
The common well-known types (google.protobuf.Timestamp, Duration, Struct, Value, ListValue, Empty, Any, FieldMask and the wrapper types) are built in, so you don’t need to select their files.
The chosen file names appear next to the button. Click Load .proto Files to parse them.
The request saves the file paths, not the files. If you share the workspace through Git, other people need the same files at the same paths, or they can use reflection instead.
Write the message
Section titled “Write the message”The Message tab holds the request message as JSON, in the standard Protocol Buffers JSON mapping: field names in lowerCamelCase, 64-bit integers as strings, enums by name, bytes as base64 and Timestamp as an RFC 3339 string such as "2024-01-02T03:04:05Z". A key that isn’t a field of the message is an error, reported with its JSON path. Replies use the same mapping and leave out fields that hold their default value.
| Control | What it does |
|---|---|
| Generate Example | Replaces the message with an example for the selected method’s input type. Appears once a schema is loaded and a method is selected. |
| Saved | Keeps messages you reuse. Save Current Message adds one; choose one to load it; Delete removes one. |
{{variables}} are filled in before the JSON is parsed, for example { "id": "{{userId}}" }.
Metadata
Section titled “Metadata”The Metadata tab is a key/value table sent as gRPC metadata (HTTP/2 headers). Keys and values can use {{variables}}. For binary metadata, end the key with -bin and give the value as base64, as in trace-context-bin. You can override content-type and user-agent (the default is cloak-proxy-grpc/1.0). Other keys the transport owns, such as te, grpc-timeout and grpc-encoding, are ignored.
Put credentials here, for example authorization with Bearer {{token}}. Keep the token itself in an environment secret or the vault.
Settings
Section titled “Settings”| Setting | Default | What it does |
|---|---|---|
| Deadline (seconds) | 30 |
How long the call may take before it ends with DEADLINE_EXCEEDED. 0 means no deadline when you invoke from the editor. |
| Skip TLS certificate verification | Off | Accepts any server certificate, for servers with self-signed certificates. |
Call types
Section titled “Call types”The menu shows each method’s call type, and the type also appears at the right of the reflection row once a method is selected.
| Call type | In the editor |
|---|---|
| Unary | Invoke sends the message and closes the request side. One reply and a status come back. |
| Server Streaming | Invoke sends the message. Each reply is logged as it arrives, then the status. |
| Client Streaming | Invoke sends the first message and keeps the stream open. Send Message sends the editor’s current JSON as another message. End Stream closes your side, and the server answers with its reply and status. |
| Bidirectional Streaming | Like client streaming, but replies can arrive at any time while you send. |
While a call is active, Invoke becomes Cancel, which cancels the call.
Read the replies
Section titled “Read the replies”Every event of the call is an entry in the Messages log:
| Entry | Meaning |
|---|---|
Calling Service.Method |
The call started. |
| Headers | The server’s response metadata. |
| Sent message #1 | A message you sent, as JSON. |
| Stream ended (client) | You closed the request side. |
| Message #1 · 42 bytes · 18 ms | A reply, decoded to JSON, with its size on the wire and the time since the call started. If it can’t be decoded, the entry shows the decoding error and its raw bytes. |
| Status OK (0) or Status NOT_FOUND (5): message | The final status and trailing metadata. |
| Call failed | The connection or call failed before a status arrived. |
Select an entry to see its content below the list as a JSON tree, text or hex. Hide events hides informational entries, the search field filters by title and content, and Clear empties the log. The status of the last call also appears at the right of the reflection row, in green for OK and red otherwise.
The connection stays open between calls on the same request, so later calls are faster. Replies up to 16 MB per message are accepted.
Run gRPC requests in the collection runner
Section titled “Run gRPC requests in the collection runner”The collection runner and cloakctl run a gRPC request in one step: they load the schema (by reflection or from the saved files), call the saved method with the saved message and metadata, and turn the outcome into an HTTP-style response so tests can check it.
| Response part | Value |
|---|---|
| Status code | The gRPC status mapped to HTTP (table below). |
| Status text | OK, or the gRPC status with its message, such as NOT_FOUND (5): user not found. |
| Headers | Response headers and trailers, plus grpc-status (the numeric code), grpc-message when the server sent one, and Content-Type: application/json. |
| Body | The reply message as JSON. For server streaming and bidirectional calls, a JSON array of every reply. |
For client streaming and bidirectional methods, a JSON array in the message sends one message per item. The deadline is the smaller of the request’s Deadline and the run’s request timeout (30 seconds by default).
| gRPC status | HTTP status |
|---|---|
OK (0) |
200 |
CANCELLED (1) |
499 |
INVALID_ARGUMENT (3), FAILED_PRECONDITION (9), OUT_OF_RANGE (11) |
400 |
DEADLINE_EXCEEDED (4) |
504 |
NOT_FOUND (5) |
404 |
ALREADY_EXISTS (6) |
409 |
PERMISSION_DENIED (7) |
403 |
RESOURCE_EXHAUSTED (8) |
429 |
UNIMPLEMENTED (12) |
501 |
UNAVAILABLE (14) |
503 |
UNAUTHENTICATED (16) |
401 |
| Any other code | 500 |
A gRPC error status is a response, not a failure, so tests run and can check it. A connection failure, a missing method (The server doesn’t have …) or Choose a gRPC method first is reported as an error with no response.
gRPC requests have no Scripts tab of their own. Put tests in the collection’s or a folder’s post-response script; they run for every request inside, so check pm.info.requestName when a test is only meant for one request:
if (pm.info.requestName === "Get user (gRPC)") { pm.test("call succeeded", () => { pm.response.to.have.status(200); pm.expect(pm.response.headers.get("grpc-status")).to.eql("0"); }); pm.test("returns the user", () => { pm.expect(pm.response.json().email).to.eql("ada@example.com"); });}See Scripts and tests.