rpc2_adapter: lowercase service-method wire names (#90 Phase 3a gap) #100

Merged
timur merged 1 commit from issue-90-adapter-lowercase-methods into development 2026-05-20 23:29:58 +00:00
Owner

Adapter bug surfaced while migrating hero_logic in #90 Phase 3a.

OsisAppRpcHandler::openrpc_spec advertises service methods with PascalCase service prefixes (LogicService.example_upsert) for human discoverability, but every existing wire client — OSIS SDK, JS SDK, hero_logic's own seed code — sends lowercase. That matches the generated dispatch arms in osis_server_generated.rs, which are all lowercase.

OServer lowercased the inbound request before service-method dispatch, so both PascalCase and lowercase callers worked. The rpc2_adapter was registering the spec's PascalCase name verbatim with RpcModule::register_method (case-sensitive), so any lowercase request hit -32601 Method not found.

Fix:

  • Register name.to_lowercase() as the wire name in register_methods.
  • Pass the same lowercase name into handle_service_call_with_context (matches the codegen's match arms exactly).
  • Dedupe by case-folded name so two spec entries that case-fold to the same wire name don't panic register_method.
  • New test service_methods_register_lowercased pins the registered form.

/openrpc.json + rpc.discover keep returning PascalCase for discovery — only the JSON-RPC wire path is lowercased. Same effective contract OServer had.

Adapter bug surfaced while migrating hero_logic in [#90](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/90) Phase 3a. `OsisAppRpcHandler::openrpc_spec` advertises service methods with PascalCase service prefixes (`LogicService.example_upsert`) for human discoverability, but every existing wire client — OSIS SDK, JS SDK, hero_logic's own seed code — sends lowercase. That matches the generated dispatch arms in `osis_server_generated.rs`, which are all lowercase. OServer lowercased the inbound request before service-method dispatch, so both PascalCase and lowercase callers worked. The rpc2_adapter was registering the spec's PascalCase name verbatim with `RpcModule::register_method` (case-sensitive), so any lowercase request hit `-32601 Method not found`. Fix: - Register `name.to_lowercase()` as the wire name in `register_methods`. - Pass the same lowercase name into `handle_service_call_with_context` (matches the codegen's `match` arms exactly). - Dedupe by case-folded name so two spec entries that case-fold to the same wire name don't panic `register_method`. - New test `service_methods_register_lowercased` pins the registered form. `/openrpc.json` + `rpc.discover` keep returning PascalCase for discovery — only the JSON-RPC wire path is lowercased. Same effective contract OServer had.
fix(hero_rpc_osis): rpc2_adapter — lowercase service-method wire names (#90)
Some checks failed
Test / test (push) Failing after 1m49s
Test / test (pull_request) Failing after 1m47s
edaf1b37d5
Phase 3a of hero_rpc#90 (migrating hero_logic) surfaced a real adapter
bug. The generated `OsisAppRpcHandler::openrpc_spec` publishes service
method names with their PascalCase service prefix
(`LogicService.example_upsert`) for human discoverability, but every
existing client on the wire — the OSIS SDK, the JS SDK, hero_logic's
own seed code — sends the lowercase form (`logicservice.example_upsert`).
That matches the `match req.method` arms `osis_server_generated.rs`
emits, which are all lowercase. OServer's `unified_server.rs` lowercased
the inbound request *before* the service-method dispatch fallback, so
both PascalCase and lowercase callers worked.

The rpc2_adapter registered the spec's PascalCase name verbatim with
`RpcModule::register_method`. jsonrpsee does case-sensitive method
lookup, so any lowercase request from a real client was rejected with
`-32601 Method not found`. The CRUD path was already correct (type
names lowercased before registration); only the service-method path
had the bug.

This commit:
- Registers `name.to_lowercase()` as the wire name in `register_methods`.
- Passes the same lowercased name into
  `handle_service_call_with_context`, matching the generated dispatch
  arms exactly.
- Deduplicates by case-folded name so two spec entries that fold to the
  same wire name don't panic `register_method`. (Real specs shouldn't
  produce this — defensive guard.)
- Adds `service_methods_register_lowercased` test pinning that
  `register_methods` registers the lowercased form and never the
  PascalCase one.

`rpc.discover` + `GET /openrpc.json` keep returning the PascalCase
display form — discovery is unaffected. Only the actual JSON-RPC wire
name flips. Same effective contract OServer had: callers send lowercase,
spec advertises PascalCase, both routes converge on the same handler.
timur merged commit da30b0732c into development 2026-05-20 23:29:58 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_rpc!100
No description provided.