Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Separate JSON and protobuf representations in ConnectRPC/gRPC responses#67

Merged
lambdalisue merged 1 commit intomainfrom
feat/response-data-raw-separation
Dec 23, 2025
Merged

Separate JSON and protobuf representations in ConnectRPC/gRPC responses#67
lambdalisue merged 1 commit intomainfrom
feat/response-data-raw-separation

Conversation

@lambdalisue
Copy link
Member

Summary

  • Add response.data property with plain JSON (camelCase fields, no $typeName)
  • Keep response.raw property with original protobuf Message (includes $typeName)
  • Implement automatic field name conversion using toJson() from @bufbuild/protobuf
  • Retrieve message schemas from gRPC reflection (FileRegistry)
  • Add comprehensive field name convention documentation
  • Add tests for schema conversion and error handling

Why

Users working with ConnectRPC/gRPC responses faced a mismatch between protobuf's snake_case naming convention and JavaScript's camelCase convention. The original implementation returned raw protobuf Messages directly, which:

  1. Required users to handle snake_case field names in JavaScript code
  2. Included protobuf metadata ($typeName) that complicated JSON serialization
  3. Didn't provide a clean separation between JSON representation and protobuf features

This change addresses these issues by providing two distinct access patterns:

  • response.data: Plain JSON with camelCase fields - suitable for logging, storage, and general JavaScript usage
  • response.raw: Original protobuf Message with metadata - for users needing protobuf-specific features like field presence checking

The implementation uses gRPC reflection to retrieve message schemas and converts responses via @bufbuild/protobuf's toJson(). Error handling ensures graceful fallback to raw messages if conversion fails, preventing API breakage.

Test Plan

  • Run deno task verify - all 441 tests pass
  • Unit tests for schema conversion with valid schemas
  • Unit tests for error handling when toJson() fails
  • Integration tests verify property access works correctly
  • Type checking passes for all JSDoc examples
  • Documentation examples demonstrate both data and raw usage

…N and protobuf representations in responses

Response objects now provide two distinct data access patterns:
- response.data: Plain JSON with camelCase fields (via toJson)
- response.raw: Original protobuf Message with $typeName metadata

This separation addresses the mismatch between protobuf's snake_case
convention and JavaScript's camelCase convention. Users working with
JSON APIs get clean, serializable objects without protobuf metadata,
while users needing protobuf-specific features retain full access to
the original Message.

The implementation retrieves message schemas from gRPC reflection
(FileRegistry) and converts responses using @bufbuild/protobuf's
toJson(). Error handling ensures graceful fallback to raw messages
if conversion fails.

Changes:
- Add schema parameter to ConnectRpcResponseSuccessParams
- Implement toJson conversion in ConnectRpcResponseSuccessImpl
- Retrieve output schemas in all 4 RPC methods (call, serverStream, clientStream, bidiStream)
- Match methods by localName (camelCase) instead of name (PascalCase)
- Add comprehensive field name convention documentation
- Add tests for schema conversion and error handling
@lambdalisue lambdalisue merged commit be5983d into main Dec 23, 2025
2 checks passed
@lambdalisue lambdalisue deleted the feat/response-data-raw-separation branch December 23, 2025 11:47
@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 66.66667% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/probitas-client-connectrpc/client.ts 40.00% 12 Missing ⚠️
packages/probitas-client-connectrpc/response.ts 94.73% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant