Skip to content

feat(server): allow RPC calls without data#853

Merged
dinwwwh merged 1 commit into
mainfrom
feat/client-server/rpc-serializer-support-deserialize-undefined
Aug 11, 2025
Merged

feat(server): allow RPC calls without data#853
dinwwwh merged 1 commit into
mainfrom
feat/client-server/rpc-serializer-support-deserialize-undefined

Conversation

@dinwwwh
Copy link
Copy Markdown
Member

@dinwwwh dinwwwh commented Aug 11, 2025

  • underline rpc serializer support deserialize undefined data
  • any serializer should accept undefined as valid deserialize data

Summary by CodeRabbit

  • Bug Fixes

    • RPC calls with no input are now handled correctly during deserialization, preventing errors when invoking endpoints without parameters.
  • Documentation

    • Updated RPC protocol docs: clarified routing example and replaced the previous GET-parameter example with a concise router-based example.
  • Tests

    • Added unit tests to cover deserialization of undefined input, improving confidence in behavior for parameter-less RPC endpoints.

- underline rpc serializer support deserialize `undefined` data
- any serializer should accept `undefined` as valid deserialize data
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 11, 2025

Walkthrough

Updates docs to alter RPC routing example, adds undefined-input handling in StandardRPCSerializer.deserialize, and introduces a unit test asserting deserialize(undefined) returns undefined.

Changes

Cohort / File(s) Summary of changes
Docs: RPC routing example
apps/content/docs/advanced/rpc-protocol.md
Replaced GET query example with plain path; updated narrative and added a TS router example using os.handler.
Client serializer: undefined handling
packages/client/src/adapters/standard/rpc-serializer.ts
Added early return in deserialize for undefined inputs with docs/TODO; existing JSON/FormData paths unchanged.
Tests: serializer deserialize
packages/client/src/adapters/standard/rpc-serializer.test.ts
New test ensures serializer.deserialize(undefined) returns undefined.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant Serializer as StandardRPCSerializer
  participant Json as StandardRPCJsonSerializer

  Caller->>Serializer: deserialize(data)
  alt data is undefined
    Serializer-->>Caller: return undefined
  else data is not FormData
    Serializer->>Json: deserialize(data)
    Json-->>Serializer: parsed
    Serializer-->>Caller: result
  else data is FormData
    Serializer->>Serializer: parse entries/blobs
    Serializer->>Json: deserialize(parsed JSON fields)
    Json-->>Serializer: parsed
    Serializer-->>Caller: result
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • unnoq/orpc#269 — Touches the same serializer area, adjusting serialize/#serialize behavior related to undefined payloads.
  • unnoq/orpc#340 — Refactors error-handling utilities used within deserialize logic in the same serializer module.

Suggested labels

size:M

Poem

A hop, a skip—no args to find,
The wire goes hush, with peace of mind.
Serializer nods: “undefined,”
Tests applaud, all green aligned.
Docs reroute—new trails we bind.
ʕ•ᴥ•ʔ… just kidding—(=^・^=) bunny signed. 🥕

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/client-server/rpc-serializer-support-deserialize-undefined

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@vercel
Copy link
Copy Markdown

vercel Bot commented Aug 11, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
orpc ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 11, 2025 8:34am

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Aug 11, 2025
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @unnoq, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

I've implemented a new feature that allows RPC calls to be made without explicitly providing data. Previously, even for calls with no data, a ?data={} parameter was required. This change streamlines the RPC protocol by enabling the StandardRPCSerializer to correctly deserialize undefined data, making the ?data={} parameter unnecessary for such calls.

Highlights

  • Documentation Update: The RPC protocol documentation has been updated to reflect the new way of making RPC calls without data, removing the need for ?data={} in the example.
  • RPC Serializer Enhancement: The StandardRPCSerializer now includes logic to explicitly handle and deserialize undefined data, allowing RPC endpoints to be called without any arguments.
  • New Test Case: A new test has been added to standardRPCSerializer.test.ts to ensure that the serializer correctly deserializes undefined input.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to allow RPC calls without data by enabling the client-side RPC serializer to handle undefined during deserialization. The changes include updating the documentation to reflect this, adding a test case for deserializing undefined, and modifying the StandardRPCSerializer.

The changes are generally good, but I've identified a couple of areas for improvement:

  • The documentation update could be more explicit about the purpose of the change.
  • There's a potential crash in the deserializer when handling null input, which is closely related to the undefined handling being added.

I've provided specific suggestions for both points in the review comments.

Comment thread packages/client/src/adapters/standard/rpc-serializer.ts
Comment thread apps/content/docs/advanced/rpc-protocol.md
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Aug 11, 2025

More templates

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@853

@orpc/client

npm i https://pkg.pr.new/@orpc/client@853

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@853

@orpc/experimental-durable-event-iterator

npm i https://pkg.pr.new/@orpc/experimental-durable-event-iterator@853

@orpc/hey-api

npm i https://pkg.pr.new/@orpc/hey-api@853

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@853

@orpc/json-schema-typed

npm i https://pkg.pr.new/@orpc/json-schema-typed@853

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@853

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@853

@orpc/openapi-client

npm i https://pkg.pr.new/@orpc/openapi-client@853

@orpc/otel

npm i https://pkg.pr.new/@orpc/otel@853

@orpc/react

npm i https://pkg.pr.new/@orpc/react@853

@orpc/react-query

npm i https://pkg.pr.new/@orpc/react-query@853

@orpc/server

npm i https://pkg.pr.new/@orpc/server@853

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@853

@orpc/solid-query

npm i https://pkg.pr.new/@orpc/solid-query@853

@orpc/standard-server

npm i https://pkg.pr.new/@orpc/standard-server@853

@orpc/standard-server-aws-lambda

npm i https://pkg.pr.new/@orpc/standard-server-aws-lambda@853

@orpc/standard-server-fetch

npm i https://pkg.pr.new/@orpc/standard-server-fetch@853

@orpc/standard-server-node

npm i https://pkg.pr.new/@orpc/standard-server-node@853

@orpc/standard-server-peer

npm i https://pkg.pr.new/@orpc/standard-server-peer@853

@orpc/svelte-query

npm i https://pkg.pr.new/@orpc/svelte-query@853

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@853

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@853

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@853

@orpc/vue-colada

npm i https://pkg.pr.new/@orpc/vue-colada@853

@orpc/vue-query

npm i https://pkg.pr.new/@orpc/vue-query@853

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@853

commit: 585d7ed

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
packages/client/src/adapters/standard/rpc-serializer.ts (1)

80-103: Server-side RPCCodec: add undefined guard before deserializing
The client’s StandardRPCSerializer now correctly handles undefined, but the server counterpart in packages/server/src/adapters/standard/rpc-codec.ts does not. If an RPC is called without arguments, await request.body() may be undefined, leading to an unexpected error when calling this.serializer.deserialize(undefined).

Please update as follows:
• File: packages/server/src/adapters/standard/rpc-codec.ts
• Location: around the deserialize call (currently line 19)

--- packages/server/src/adapters/standard/rpc-codec.ts
@@ async decode(request) {
-   const serialized = await request.body();
-   return this.serializer.deserialize(serialized);
+   const serialized = await request.body();
+   if (serialized === undefined) {
+     return undefined;
+   }
+   return this.serializer.deserialize(serialized);
}

Optionally, review the OpenAPI server codec in packages/openapi/src/adapters/standard/openapi-codec.ts—its body path also calls this.serializer.deserialize(await request.body()) without an undefined check.

🧹 Nitpick comments (5)
apps/content/docs/advanced/rpc-protocol.md (1)

18-26: Provide context for os.handler in the snippet

The snippet uses os.handler without showing where os comes from. Add a one-line import or a short note to avoid confusion.

Would you confirm the intended import? For example:

// e.g., if this is correct for your docs:
import { os } from '@orpc/standard-server'
packages/client/src/adapters/standard/rpc-serializer.test.ts (2)

197-200: Nit: improve test name phrasing

Consider renaming for readability.

-it('standardRPCSerializer support deserialize undefined data', () => {
+it('standardRPCSerializer supports deserializing undefined data', () => {

197-200: Consider adding a complementary round-trip test for serialize(undefined)

To lock in expectations documented in the serializer comment, add a test asserting that:

  • serialize(undefined) returns an object (not undefined), and
  • deserializing that object yields undefined.

This helps ensure future changes don’t inadvertently alter the serialization shape for no-arg calls.

I can draft this test if helpful.

packages/client/src/adapters/standard/rpc-serializer.ts (2)

81-90: Docstring polish

Minor clarity tweak.

-/**
- * Only deserializing undefined is supported, while the return of serialize(undefined) is always an object.
- * This is for supporting calling RPC endpoints without arguments.
- *
- * @todo Consider supporting serialize(undefined) -> undefined in the future
- */
+/**
+ * Only deserialization of `undefined` is special-cased here; `serialize(undefined)` always returns an object.
+ * This supports calling RPC endpoints without arguments.
+ *
+ * @todo Consider supporting `serialize(undefined) -> undefined` in the future
+ */

80-103: Optional: tighten the private method parameter type

If convenient, consider #deserialize(data: unknown) and then narrow. This improves type safety at the cost of some type guards/casts. Not required for this PR.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 37971b1 and 585d7ed.

📒 Files selected for processing (3)
  • apps/content/docs/advanced/rpc-protocol.md (1 hunks)
  • packages/client/src/adapters/standard/rpc-serializer.test.ts (1 hunks)
  • packages/client/src/adapters/standard/rpc-serializer.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/client/src/adapters/standard/rpc-serializer.test.ts (1)
packages/client/src/adapters/standard/rpc-serializer.ts (1)
  • StandardRPCSerializer (7-104)
packages/client/src/adapters/standard/rpc-serializer.ts (1)
packages/openapi-client/src/adapters/standard/openapi-serializer.ts (1)
  • data (34-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: publish-commit
  • GitHub Check: lint
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
apps/content/docs/advanced/rpc-protocol.md (1)

15-16: Good: Routing example without data aligns with no-argument RPC calls

Shows that calling a procedure via path alone is valid. This complements the new undefined-deserialization support.

packages/client/src/adapters/standard/rpc-serializer.test.ts (1)

197-200: Covers the undefined path—LGTM

The test correctly asserts that deserialize(undefined) returns undefined, matching the new behavior.

packages/client/src/adapters/standard/rpc-serializer.ts (1)

81-90: Correct and necessary: safely handle undefined input in #deserialize

Early-returning undefined avoids runtime errors and enables no-argument RPC calls. This aligns with the PR objective.

@dinwwwh dinwwwh merged commit 890a8ab into main Aug 11, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant