Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(server): short-hand routers and spread support #5404

Merged
merged 39 commits into from Jan 30, 2024
Merged

Conversation

KATT
Copy link
Member

@KATT KATT commented Jan 26, 2024

  • Allow for creating routers that are just objects
  • Will simplify .d.ts-files for people who use satisfies TRPCRouterRecord

Closes #3630

Could help make #4129 easier

How it looks like

This will allow you to define routers like this:

const post = {
  byId: t.procedure.query(() => '..'),
} satisfies RouterRecord; // <--  ✨ using satisfies for sub-routers could(?) be less heavy for the compiler and `.d.ts`-files



const appRouter = t.router({
  post,
  // ✨ short-cut routers by doing a `{}`
  deeply: {
    nested: {
      greeting: t.query(() => '...'),
    },
  },
});

Copy link

vercel bot commented Jan 26, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
next-prisma-starter ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 29, 2024 1:30pm
og-image ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 29, 2024 1:30pm
trpc-next-app-dir ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 29, 2024 1:30pm
www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 29, 2024 1:30pm

? DecoratedProcedureRecord<TRouter, TProcedures[TKey]['_def']['record']>
: TProcedures[TKey] extends AnyProcedure
? DecorateProcedure<TRouter['_def']['_config']['$types'], TProcedures[TKey]>
[TKey in keyof TRecord]: TRecord[TKey] extends infer $Value
Copy link
Member

Choose a reason for hiding this comment

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

why do you need this extends infer here?

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 think it makes the "looping" clearer

Copy link
Member Author

Choose a reason for hiding this comment

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

Only need to grab TRecord[Key] once, it's like a declaring a variable

Copy link
Member

Choose a reason for hiding this comment

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

Only need to grab TRecord[Key] once, it's like a declaring a variable

aah i see, how is the compiler performance comparatively?

Copy link
Member Author

Choose a reason for hiding this comment

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

No idea tbh 🙈

Comment on lines +31 to +34
const merged = t.router({
...router1,
...router2,
});
Copy link
Member

Choose a reason for hiding this comment

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

niceee - can we deprecate this monstosity then?

https://github.com/trpc/trpc/blob/next/packages/server/src/unstable-core-do-not-import/router.ts#L272-L309

or maybe just make it an alias?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes that'd be nice

Copy link
Member Author

Choose a reason for hiding this comment

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

we could alias it

Copy link
Member

@juliusmarminge juliusmarminge left a comment

Choose a reason for hiding this comment

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

Great work, only nitpick I'd point out is that there's a lot of these:

  TRouter['_def']['_config']['$types'],
  TRouter['_def']['record']

don't we have inference helpers for those?

  inferRootTypes<TRouter>
  ...

?

@KATT
Copy link
Member Author

KATT commented Jan 29, 2024

Great work, only nitpick I'd point out is that there's a lot of these:

  TRouter['_def']['_config']['$types'],
  TRouter['_def']['record']

don't we have inference helpers for those?

  inferRootTypes<TRouter>
  ...

?

I'd be fine to change that, I'd also be happy if we changed the router so the grabbing would just be e.g.

  • TRouter['_def']['$types']
  • TRouter['_def']['_config']['$types']
  • TRouter[RootTypesSymbol]
  • TRouter['_config']['$types']

I think that sort of approach would be even nicer than using a helper - it feels like an unnecessary abstraction

Copy link
Member

@juliusmarminge juliusmarminge left a comment

Choose a reason for hiding this comment

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

i see that you can't spread actual routers:

// router/post.ts
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";

export const authRouter = createTRPCRouter({
  getSession: publicProcedure.query(({ ctx }) => {
    return ctx.session;
  }),
  getSecretMessage: protectedProcedure.query(() => {
    // testing type validation of overridden next-auth Session in @acme/auth package
    return "you can see this secret message!";
  }),
});

// root.ts
import { authRouter } from "./router/auth";
import { postRouter } from "./router/post";
import { createTRPCRouter } from "./trpc";

export const appRouter = createTRPCRouter({
  auth: authRouter,
  post: postRouter,
  ...authRouter, // <-- doesn't work
});

// export type definition of API
export type AppRouter = typeof appRouter;

how do you make the typesystem / proxy understand spread? if we to alias mergeRouters to this implementation we should support spreading routers and not just records?

CleanShot 2024-01-30 at 08 42 50@2x

@KATT
Copy link
Member Author

KATT commented Jan 30, 2024

i see that you can't spread actual routers:

// router/post.ts
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";

export const authRouter = createTRPCRouter({
  getSession: publicProcedure.query(({ ctx }) => {
    return ctx.session;
  }),
  getSecretMessage: protectedProcedure.query(() => {
    // testing type validation of overridden next-auth Session in @acme/auth package
    return "you can see this secret message!";
  }),
});

// root.ts
import { authRouter } from "./router/auth";
import { postRouter } from "./router/post";
import { createTRPCRouter } from "./trpc";

export const appRouter = createTRPCRouter({
  auth: authRouter,
  post: postRouter,
  ...authRouter, // <-- doesn't work
});

// export type definition of API
export type AppRouter = typeof appRouter;

how do you make the typesystem / proxy understand spread? if we to alias mergeRouters to this implementation we should support spreading routers and not just records?

No idea, but I think most people use sub-routers with the other way, so might be a non-issue

@KATT KATT merged commit 05798dd into next Jan 30, 2024
39 checks passed
@KATT KATT deleted the 01-26-no-proc-router-rec branch January 30, 2024 09:16
Copy link

This pull request has been locked because we are very unlikely to see comments on closed issues. If you think, this PR is still necessary, create a new one with the same branch. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 31, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: add shorthand {} for sub-routers
2 participants