Skip to content

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.

  1. 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.

  2. Type the server’s address in the URL bar, for example grpcs://api.example.com:443 or grpc://localhost:50051.

  3. 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.

  4. 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.

  5. Edit the JSON in Message and add any metadata in Metadata.

  6. 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.

  1. Server address
  2. Method menu, with each method's call type
  3. Invoke (⌘↩)
  4. Load the schema by reflection or from .proto files
  5. Message, Metadata and Settings tabs
  6. Messages log: every message, header and status
A gRPC request to grpcs://grpcb.in:9001 with a method menu reading Load methods first, a Load via Server Reflection button, and Message, Metadata and Settings tabs above an empty Messages log

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.

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.

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.

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}}" }.

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.

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.

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.

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:

Collection post-response script
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.