Skip to content

Conversation

@sandros94
Copy link
Member

@sandros94 sandros94 commented Aug 2, 2025

An experimental handler to support the JSON RPC spec.

Usage

you define it like a normal handler, but with the added params as its first callback argument:

const eventHandler = defineJsonRpcHandler({
  echo: (params, event) => {
    return `Recieved \`${params}\` on path \`${event.url.pathname}\``;
  },
});
app.post("/rpc"; eventHandler); // Must be a POST method

then you call it with a valid body, for example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "echo",
  "params": "Hello World",
}

and you'll receive a json-rpc compatible response:

{
  "jsonrpc": "2.0",
  "id": 1, // Same id from the request
  "result": "Recieved `Hello World` on path `/rpc`",
}

it also support client-to-server notifications by simply omitting the id key, this will result in the server responding a 202

Personal considerations and future expansion

  • Support built-in schema validation (probably allowing for an object instead of directly the event callback)

@sandros94 sandros94 requested a review from pi0 as a code owner August 2, 2025 11:00
@sandros94 sandros94 self-assigned this Aug 2, 2025
@sandros94 sandros94 added the enhancement New feature or request label Aug 2, 2025
@codecov
Copy link

codecov bot commented Aug 2, 2025

Codecov Report

❌ Patch coverage is 91.94631% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/utils/json-rpc.ts 91.89% 12 Missing ⚠️

📢 Thoughts on this report? Let us know!

}

const { id, method, params } = req;
const handler = methods[method];
Copy link
Member

Choose a reason for hiding this comment

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

It seems we might need some builtin protection against proto access

Copy link
Member Author

Choose a reason for hiding this comment

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

with b25d034 I've implemented a simple safeguard for it.

Let me know if I'm on the right track, as I do realize this is a topic which I'm weak in knowledge :/

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Aug 2, 2025

Deploying h3dev with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4d0d8c0
Status: ✅  Deploy successful!
Preview URL: https://d4d2748b.h3dev.pages.dev
Branch Preview URL: https://feat-json-rpc-handler.h3dev.pages.dev

View logs

@sandros94 sandros94 changed the title feat(handler): new jsonRpcHandler feat(handler): new defineJsonRpcHandler Aug 2, 2025
@pi0
Copy link
Member

pi0 commented Aug 27, 2025

Hi dear @sandros94 This PR is under my radar (and important!) but have to delay for more testing. In meantime you don't need to keep it updated ❤️

@sandros94
Copy link
Member Author

Hi dear @sandros94 This PR is under my radar (and important!) but have to delay for more testing. In meantime you don't need to keep it updated ❤️

Absolutely no problem, I also imagine that we all took some time off for the summer and should focus on more important things first, this is a long term one. This feature is also easy to implement in downstream projects, so no rush.

The reason why I kept updating it for a bit was because while testing it with some Json RPC clients (mainly MCP-related ones) I've found a couple of issues and DX improvements, but now it is complete for what I know atm


// For a single request, return the single response object.
// For a batch request, return the array of response objects.
return isBatch ? finalResponses : finalResponses[0];
Copy link
Member Author

Choose a reason for hiding this comment

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

Suggested change
return isBatch ? finalResponses : finalResponses[0];
return isBatch ? finalResponses : finalResponses[0];

@pi0 Would this block an event-stream for non-batch requests? (a final response currently is { jsonrpc: "2.0", id, result })

Doesn't have a strict approach on this, but MCP servers that do want to support SSE state that at the end of the stream a full jsonrpc response should be provided anyway

I'm having an hard time testing event streams even in normal h3 routes 😬

Copy link
Member Author

Choose a reason for hiding this comment

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

I just found a better approach, much simpler and only relies on ReadableStream

Copy link
Member Author

Choose a reason for hiding this comment

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

pushed with 9c19de6, this one can be marked as resolved (I see it as Pending and I cannot close it)

Copy link
Member Author

Choose a reason for hiding this comment

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

I've never noticed these were left as pending...

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants