upstash / jstack

Confidently ship high-performance, low-cost Next.js apps
MIT License
913 stars 54 forks source link

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

Open utopyin opened 2 months ago

utopyin commented 2 months ago

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:

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 ✌️

joschan21 commented 2 months ago

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