trpc / v10-playground

tRPC v10 procedure play
https://stackblitz.com/github/trpc/v10-playground?file=src%2Fserver%2Findex.ts,src%2Fclient.ts,src%2Fserver%2Frouters%2FpostRouter.ts&view=editor
13 stars 3 forks source link

POCs for function-like hooks #22

Closed colinhacks closed 2 years ago

colinhacks commented 2 years ago

Not a real PR, just proofs of concept. Two proposed APIs. Both require Proxy.

Flat "function-call" API

const flatClient = createFlatClient<typeof appRouter>();
const greeting = await flatClient.query.greeting({ hello: 'string' });
const posts = await flatClient.query['post.all']();

Nested "function-call" API

const nestedClient = createNestedClient<typeof appRouter>();
const greeting = await nestedClient.query.greeting({ hello: 'string' });
const posts = await nestedClient.query.post.all();

I prefer the nested version personally. Since both of these require Proxy you might as well try to maintain the "feel"/illusion of a router hierarchy.

Router merging

If you go with the nested version, I think the router merging API should add periods under the hood, instead of doing a simple concatenation. Since the nested client API treats the period as a special character, it shouldn't be the job of the developer to include it. Rather, using periods in procedure names should be discouraged/disallowed. It's also just looks cleaner.

// server
const postRouter = trpc.router()
  .query('fetch', {
    resolve(params){ return []; }
  });

const appRouter = trpc.router()
  .merge('post', postRouter) // "post" not "post."

// client
client.query.post.fetch()

You could make this a non-breaking change by implementing this new behavior as a new method. Some options:

trpc.router().subrouter('post', postRouter)
trpc.router().compose('post', postRouter)
trpc.router().use('post', postRouter)