jstack icon indicating copy to clipboard operation
jstack copied to clipboard

Routes with path parameters can't be called by the RPC client

Open utopyin opened this issue 1 year ago • 1 comments

Context

The current validation of inputs happens inside the router helper function, and the schema validation is done against either the parsed query or the parsed body depending on the type of OperationType (either QueryOperation or MutationOperation for now).

Then, the router returns a Hono instance with typed endpoints to allow the RPC client to pass directly the query/body data inside $get or $post without getting Typescript mad.

But as the Hono server still expects

{
  query: {
    name: string
  }
}

and not

{
  name: string
}

so we have to proxy the RPC client to reshape the argument of $get and $post (as Hono expects it) before sending the request.

The issue

As we manually edit the shape of what's passed into $get or $post, we prevent the use of param.

And even if we passed this

client.post[":user_id"].create.$post({
  name: "Josh",
  param: {
    user_id: "123"
  }
})

it would still end up being sent as the following payload thanks (or not) to the proxy of the RPC client.

client.post[":user_id"].create.$post({
  query: {
    name: "Josh",
    param: {
      user_id: "123"
    }
  }
})

This is pretty annoying as it makes every path with parameters not callable by the RPC client.

I haven't given much thought to a potential solution, but those are the two ideas that came up off the top of my head:

  • Implement the more native approach with validator() or zValidator() and remove the proxy on the RPC client
  • Infer path parameters in the type of the router and add support for them in the proxy of the RPC client

I would opt for the first solution, as zValidator() is great and already supports every validation targets (json, query, header, param, cookie and form).

What do you guys think? I can work on a PR if needed ✌️

utopyin avatar Sep 10 '24 23:09 utopyin

interesting thought, how would the ideal RPC call from the FE or server component look like in this case? Afaik in trpc you'd just pass the params instead as body request props

joschan21 avatar Sep 16 '24 10:09 joschan21