github unkn0wn-root/resterm v0.51.1

3 hours ago

v0.51.1

Long awaited release with love for gRPC. gRPC gets working @auth, authenticated reflection, predictable stream timeouts, message size and compression settings and google.rpc.* status details in the UI and in JSON reports.

gRPC authentication

@auth now applies to gRPC requests. basic, bearer, apikey, and header auth are sent as metadata, and so are command and oauth2 once their header is resolved.

### List orders over gRPC
# @grpc orders.OrderService/List
# @auth bearer {{auth.token}}
GRPC {{grpc.host}}

{ "pageSize": 20 }

Explicit metadata wins over generated auth. A key set with @grpc-metadata (or a header line) is never overwritten by inherited @auth and the auth parameters are not even expanded:

### Same call with a pinned token
# @auth file bearer {{auth.token}}
# @grpc orders.OrderService/List
# @grpc-metadata authorization: Bearer {{debug.token}}
GRPC {{grpc.host}}

{}

apikey with placement query is now rejected on gRPC with a clear error, since gRPC has no query string. Use the default header placement instead:

# @auth apikey header X-API-Key {{api.key}}

Reflection also carries request metadata now, on both the v1 and v1alpha reflection services, so servers that require auth on reflection can serve descriptors instead of failing with Unauthenticated before the call starts.

Timeouts

Setup (dial plus descriptor resolution), unary calls, and streams each get their own deadline.

A timeout declared on the request itself bounds the whole stream:

### Tail events for two minutes, then stop
# @timeout 2m
# @grpc events.EventService/Watch
GRPC {{grpc.host}}

{ "topic": "orders" }

The stream ends with DeadlineExceeded after two minutes. # @setting timeout 2m on the request behaves the same way.

A timeout inherited from file settings, an environment, or the app default no longer applies to streams, so a 30s default cannot kill a long-lived subscription. Streams without a request-local timeout run until the server ends them or you cancel from the Stream tab.

New gRPC settings

  • @setting grpc-max-recv-size 16MB raises the maximum response message size (gRPC defaults
  • @setting grpc-max-send-size 32MB raises the maximum request message size.
  • @setting grpc-compression gzip compresses request messages. none turns it off, and compressed responses are always accepted.
### Upload a large payload
# @grpc media.MediaService/Upload
# @setting grpc-max-send-size 32MB
# @setting grpc-max-recv-size 16MB
# @setting grpc-compression gzip
GRPC {{grpc.host}}

< ./payload.json

Sizes accept plain bytes and units, for example 4096, 1KiB, 8MB. Bad values fail the request with a message that names the setting, such as invalid grpc-max-recv-size "huge" (use a size such as 8MB). These settings work at request, file, and environment scope like other @setting keys, and are offered by autocomplete.

Status details

A failing call now decodes any google.rpc.* details the server attached and shows them undresponse pane. They are also included in machine-readable reports:

resterm run --request list-orders --format json ./orders.http
"GRPC": {
  "Code": "InvalidArgument",
  "StatusCode": 3,
  "StatusMessage": "invalid page size",
  "StatusDetails": [
    "{\"@type\":\"type.googleapis.com/google.rpc.RetryInfo\",\"retryDelay\":\"5s\"}"
  ]
}

Custom detail types are decoded through the descriptors already loaded for the request. A detail that cannot be decoded is skipped rather than failing the response.

File resolution for gRPC

Descriptor sets and message files now follow the same lookup rules as HTTP body files: relative to the request file first, then the configured fallback roots.

### Call without reflection
# @grpc orders.OrderService/List
# @grpc-descriptor ./protos/orders.protoset
# @grpc-reflection false
GRPC {{grpc.host}}

< ./payloads/list.json

Explicit credentials

If a request already supplies the credential header itself (a header line, or @grpc-metadata), Resterm no longer fetches an OAuth token or runs an @auth command. An inherited @auth oauth2 that is missing token_url also stops erroring in that case, because the config is discarded anyway.

### Inherited oauth2 is not used here
# @auth file oauth2 token_url={{oauth.tokenUrl}} cache_key=myapi

GET https://api.example.com/orders
Authorization: Bearer {{debug.token}}

Workspace and file handling

  • Request, script, environment, GraphQL, JSON, and JavaScript classification is centralized,kind instead of treating the zero value as a request file.
  • Recursive workspace scans skip unreadable nested paths instead of aborting, while an unreadable root still returns an error.
  • Explicit env file containment and deduplication are preserved.

Compatibility Notes

  • Explicit gRPC metadata takes precedence over generated standard header auth. If you relied on @auth overriding authorization metadata pair, the metadata now wins.
  • Request-local stream timeouts are enforced for the lifetime of the stream; inherited timeouts are not.
  • Recursive workspace discovery is more resilient but may silently omit unreadable nested paths.

Don't miss a new resterm release

NewReleases is sending notifications on new releases.