feat: gRPC settings tab — configurable message sizes, deadlines, and proto-loader options#7738
feat: gRPC settings tab — configurable message sizes, deadlines, and proto-loader options#7738sanish-bruno wants to merge 1 commit intousebruno:mainfrom
Conversation
- Introduced GrpcSettingsPane component to manage gRPC channel and request settings. - Updated GrpcRequestPane to include a new settings tab for accessing GrpcSettingsPane. - Enhanced Redux actions and gRPC client to handle new settings, including max message sizes, deadlines, and keepalive options. - Updated item settings type to accommodate new gRPC-specific settings. - Added parsing logic for gRPC settings in bruToJson.js. This feature improves user experience by allowing detailed configuration of gRPC requests directly within the application.
WalkthroughThis PR adds gRPC settings configuration across the UI, state management, IPC layer, and client code. A new "Settings" tab in the gRPC request pane allows users to configure message length limits, keepalive parameters, deadlines, and other gRPC channel options. Settings flow through Redux actions, Electron IPC handlers, and are applied as channel options, proto options, and per-RPC deadlines in the underlying gRPC client. Changes
Sequence DiagramsequenceDiagram
participant User
participant GrpcSettingsPane as GrpcSettingsPane<br/>(UI)
participant Redux as Redux<br/>(State)
participant Network as Network<br/>(IPC)
participant ElectronIPC as Electron IPC<br/>(Handler)
participant GrpcClient as gRPC Client
User->>GrpcSettingsPane: Edit settings (max message size, deadline, etc.)
GrpcSettingsPane->>Redux: Dispatch updateItemSettings & saveRequest
Redux->>Network: State updated, startGrpcRequest invoked
Network->>ElectronIPC: ipcRenderer.invoke('grpc:start-connection', {request, settings, ...})
ElectronIPC->>ElectronIPC: Construct channelOptions & protoOptions from settings
ElectronIPC->>GrpcClient: grpcClient.startConnection(request, {channelOptions, protoOptions, deadline})
GrpcClient->>GrpcClient: Apply channel options to gRPC channel
GrpcClient->>GrpcClient: Set per-RPC callOptions.deadline if deadline > 0
GrpcClient-->>User: Connection established with configured parameters
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/bruno-requests/src/grpc/grpc-client.js (1)
687-691: Consider documenting the expected unit fordeadline.The implementation correctly computes
Date.now() + deadline, but the function's JSDoc (lines 577-598) doesn't specify thatdeadlineshould be in milliseconds. A brief@param {number} [params.deadline] - Per-RPC deadline in millisecondswould prevent confusion.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/bruno-requests/src/grpc/grpc-client.js` around lines 687 - 691, Update the function JSDoc for the parameter named deadline to explicitly state its unit (milliseconds) and optional nature: add a line like "@param {number} [params.deadline] - Per-RPC deadline in milliseconds" (or similar) in the JSDoc that documents the function which builds callOptions/deadline so callers know the value is added to Date.now(); reference the existing symbol names "deadline" and the callOptions construction to ensure the doc sits next to the same function’s JSDoc comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/bruno-requests/src/grpc/grpc-client.js`:
- Around line 821-823: The call to client.getServiceMethods(packageObject,
service) is invalid because grpc-js-reflection-client exposes
listMethods(serviceName) instead; update the code that currently uses
getServiceMethods (referencing client, service, descriptor.getPackageObject and
mergedProtoOptions) to call await client.listMethods(service) and use its
returned method list, removing any dependence on getServiceMethods and
packageObject for method discovery so runtime uses the library's actual API.
---
Nitpick comments:
In `@packages/bruno-requests/src/grpc/grpc-client.js`:
- Around line 687-691: Update the function JSDoc for the parameter named
deadline to explicitly state its unit (milliseconds) and optional nature: add a
line like "@param {number} [params.deadline] - Per-RPC deadline in milliseconds"
(or similar) in the JSDoc that documents the function which builds
callOptions/deadline so callers know the value is added to Date.now(); reference
the existing symbol names "deadline" and the callOptions construction to ensure
the doc sits next to the same function’s JSDoc comment.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3dea439b-b073-42e9-ae18-e102e65339c3
📒 Files selected for processing (9)
packages/bruno-app/src/components/RequestPane/GrpcRequestPane/index.jspackages/bruno-app/src/components/RequestPane/GrpcSettingsPane/index.jspackages/bruno-app/src/providers/ReduxStore/slices/collections/actions.jspackages/bruno-app/src/utils/network/index.jspackages/bruno-electron/src/ipc/network/grpc-event-handlers.jspackages/bruno-lang/v2/src/bruToJson.jspackages/bruno-requests/src/grpc/grpc-client.jspackages/bruno-requests/src/grpc/grpc-client.spec.jspackages/bruno-schema-types/src/collection/item.ts
👮 Files not reviewed due to content moderation or server errors (8)
- packages/bruno-app/src/components/RequestPane/GrpcRequestPane/index.js
- packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
- packages/bruno-app/src/utils/network/index.js
- packages/bruno-lang/v2/src/bruToJson.js
- packages/bruno-requests/src/grpc/grpc-client.spec.js
- packages/bruno-schema-types/src/collection/item.ts
- packages/bruno-electron/src/ipc/network/grpc-event-handlers.js
- packages/bruno-app/src/components/RequestPane/GrpcSettingsPane/index.js
| const descriptor = await client.getDescriptorBySymbol(service, callOptions); | ||
| const packageObject = descriptor.getPackageObject(mergedProtoOptions); | ||
| const m = client.getServiceMethods(packageObject, service); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check the installed version and verify API surface of grpc-js-reflection-client
# Find package.json files that might have grpc-js-reflection-client
fd -t f 'package.json' | xargs grep -l 'grpc-js-reflection-client' 2>/dev/null | head -5 | while read f; do
echo "=== $f ==="
jq '.dependencies["grpc-js-reflection-client"] // .devDependencies["grpc-js-reflection-client"]' "$f"
done
# Check if there's any TypeScript definition or usage pattern in the codebase
echo "=== Searching for getDescriptorBySymbol usage ==="
rg -n 'getDescriptorBySymbol' --type js --type ts -C 2Repository: usebruno/bruno
Length of output: 1127
🌐 Web query:
grpc-js-reflection-client getDescriptorBySymbol getServiceMethods API
💡 Result:
grpc-js-reflection-client is a Node.js/TypeScript package that enables clients to interact with gRPC servers exposing reflection services, allowing dynamic retrieval of proto descriptors without static .proto files. It works with @grpc/grpc-js and @grpc/reflection (server-side). Key classes and API methods from documentation and examples: - GrpcReflection: Main client class. - new GrpcReflection(host: string, credentials: grpc.ChannelCredentials): Creates a reflection client connected to a gRPC server. - listServices: Promise<Array> - Lists all available services on the server. - listMethods(serviceName: string): Promise<Array> - Lists methods for a specific service (e.g., await client.listMethods('grpc.gateway.examples.examplepb.ABitOfEverythingService'); returns array of methods with .name). - getDescriptorByFileName(filename: string): Promise - Retrieves protobuf descriptor by proto filename (e.g., 'addressbook.proto'). - getDescriptorBySymbol(symbol: string): Promise - Retrieves protobuf descriptor by symbol name (e.g., await c.getDescriptorBySymbol('apidata');). Descriptor object methods: - getPackageObject(options): Converts to @grpc/grpc-js loadPackageDefinition format. - getDescriptorMessage: Gets protobufjs descriptor message. - getPackageDefinition(options): Gets package definition. - getBuffer: Gets raw protobuf buffer. Helper: serviceHelper(options): One-line helper to get a service client (e.g., {host, servicePath: 'addressbook.AddressesService', credentials}). Installation: npm install grpc-js-reflection-client @grpc/grpc-js Example usage: const { GrpcReflection } = require('grpc-js-reflection-client'); const grpc = require('@grpc/grpc-js'); const client = new GrpcReflection('localhost:50051', grpc.ChannelCredentials.createInsecure); const services = await client.listServices; const methods = await client.listMethods('example.Service'); const descriptor = await client.getDescriptorBySymbol('example.Symbol'); const pkg = descriptor.getPackageObject({keepCase: true, longs: String, enums: String}); const service = new pkg.example.Service('localhost:50051', grpc.ChannelCredentials.createInsecure); Package latest version 1.3.5 (Mar 2026), repo: https://github.com/gawsoftpl/grpc-js-reflection-api-client. No official gRPC docs for this third-party lib; based on README/examples.
Citations:
- 1: https://registry.npmjs.org/grpc-js-reflection-client
- 2: https://www.npmjs.com/package/grpc-js-reflection-client?ref=pkgstats.com
- 3: https://github.com/gawsoftpl/grpc-js-reflection-api-client
- 4: https://www.npmjs.com/package/grpc-js-reflection-client
- 5: https://app.unpkg.com/grpc-js-reflection-client@1.3.4/files/examples/otherMethods.ts
- 6: https://socket.dev/npm/package/grpc-js-reflection-client
🏁 Script executed:
# Check for getServiceMethods definition in grpc-client.js
rg -n 'getServiceMethods' packages/bruno-requests/src/grpc/grpc-client.js -B 5 -A 5
# Check if client is wrapped or if this is directly from the library
rg -n 'new GrpcReflection\|class.*Client' packages/bruno-requests/src/grpc/ -A 10Repository: usebruno/bruno
Length of output: 556
🏁 Script executed:
# Look for client instantiation around this code
sed -n '770,830p' packages/bruno-requests/src/grpc/grpc-client.js
# Check the test mock to see what getServiceMethods returns
rg -n 'mockGetServiceMethods' packages/bruno-requests/src/grpc/grpc-client.spec.js -B 5 -A 15Repository: usebruno/bruno
Length of output: 3492
getServiceMethods does not exist in grpc-js-reflection-client — this will fail at runtime.
The code calls client.getServiceMethods(packageObject, service) on line 823, but this method doesn't exist in the actual library. The test mocks it, which masks the real issue. According to the library documentation, use listMethods(serviceName) instead to retrieve service methods directly. Update the implementation to match the actual API:
const m = await client.listMethods(service);The documented methods on the client are getDescriptorBySymbol and listMethods — not getServiceMethods.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/bruno-requests/src/grpc/grpc-client.js` around lines 821 - 823, The
call to client.getServiceMethods(packageObject, service) is invalid because
grpc-js-reflection-client exposes listMethods(serviceName) instead; update the
code that currently uses getServiceMethods (referencing client, service,
descriptor.getPackageObject and mergedProtoOptions) to call await
client.listMethods(service) and use its returned method list, removing any
dependence on getServiceMethods and packageObject for method discovery so
runtime uses the library's actual API.
Summary
Jira
Adds a Settings tab to the gRPC request pane with configurable channel options, per-RPC deadlines, and proto-loader settings.
Closes #7718, #7737
Changes
Default channel options
Sets
grpc.max_receive_message_lengthandgrpc.max_send_message_lengthto-1(unlimited) by default — the@grpc/grpc-jslibrary defaults to 4MB, which made Bruno unusable for large gRPC responses.Configurable settings
Channel options — Max receive/send message size, keepalive time/timeout, client idle timeout, max reconnect backoff
Per-RPC call options — Deadline in milliseconds. Many gRPC servers require a deadline and reject requests without one.
Proto-loader options — Toggle whether protobuf fields with default values (0, "", false) are included in responses. Works for both proto file and reflection-based loading.
Settings persistence
Persisted in the
.brufile via the existingsettingsblock:Files changed
packages/bruno-schema-types/src/collection/item.ts— addedGrpcItemSettingsinterfacepackages/bruno-requests/src/grpc/grpc-client.js— default channel options, deadline support, proto options pass-through for both file and reflection loadingpackages/bruno-requests/src/grpc/grpc-client.spec.js— updated mocks for reflection API changepackages/bruno-lang/v2/src/bruToJson.js— parse gRPC settings from.brufilespackages/bruno-electron/src/ipc/network/grpc-event-handlers.js— map settings to channel/call/proto optionspackages/bruno-app/src/utils/network/index.js— pass settings via IPCpackages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js— pass settings for reflection loadingpackages/bruno-app/src/components/RequestPane/GrpcRequestPane/index.js— added Settings tabpackages/bruno-app/src/components/RequestPane/GrpcSettingsPane/index.js— new Settings UI componentContribution Checklist:
Summary by CodeRabbit
Release Notes