_e.g._ `?input=${JSON.stringify(encodeURIComponent(input))` |\r\n| `POST` | `.mutation()` | Input as post body. | \r\n\r\n## Considerations with OpenAPI\r\n\r\n- Resources are usually `/{resource}/{id}?param1=x¶m2=y`-style - tRPC is [currently] with `{resource}?input=JSON.stringify(encodeURIComponent(input))`-style\r\n- JSON-RPC based response shape might not be the ideal response shape for OpenAPI\r\n- An output schema usually have a `$ref`-schema which would be possible to do automatically / first feature people would request is to make different paths request the same input type\r\n- Actually using zod or any other validation on a resolver's `output` would slow down API outputs.\r\n\r\n## Related\r\n\r\nhttps://github.com/trpc/trpc/discussions/271\r\n",[2906,2908],{"name":2907,"color":2880},"🙋♂️ help wanted",{"name":2909,"color":2910},"💬 discussion","4B318A",755,"[RFC] Using tRPC for public-facing APIs (OpenAPI/Swagger/etc)","2022-06-19T00:48:45Z","https://github.com/trpc/trpc/issues/755",0.6772601,{"description":2917,"labels":2918,"number":1857,"owner":2857,"repository":2921,"state":2882,"title":2922,"updated_at":2923,"url":2924,"score":2925},"# The router API\r\n\r\n## Challenges with the current implementation\r\n\r\n- TypeScript performance. Each procedure added creates a new Router that TypeScript chokes on as the underlying complexity grows non-linearly with each added procedure - each procedure basically has its \"own instance\" within the compiler even if it's flattened and unaffected at runtime.\r\n- I find that those queries are hard/unintuitive to write, I find myself counting parentheses and curly brackets all too often. Arguably, your suggestions with the resolver API could also address this.\r\n- No CMD+click\r\n\r\n## Suggested implementation\r\n\r\n- Flat router\r\n- No automatic prefixing (breaks jump to definition / CMD+click)\r\n\r\n```tsx\r\nimport { z } from 'zod';\r\nimport { initTRPC } from './trpc/server';\r\n\r\nconst trpc = initTRPC\u003CContext>();\r\n\r\nconst postRouter = trpc.router({\r\n queries: {\r\n postById: null as any /* resolver implementation is a separate discussion */\r\n postAll: null as any /* resolver implementation is a separate discussion */\r\n },\r\n mutations: {\r\n postAdd: null as any /* resolver implementation is a separate discussion */\r\n});\r\n\r\nconst userRouter = trpc.router({\r\n queries: {\r\n userAll: null as any /* resolver implementation is a separate discussion */\r\n },\r\n);\r\n\r\nconst appRouter = trpc.mergeRouters(\r\n postRouter, \r\n userRouter, \r\n // ...\r\n)\r\n```",[2919],{"name":2920,"color":2880},"❕ RFC","v10-playground","Chapter 1) The Router API","2022-04-12T12:36:28Z","https://github.com/trpc/v10-playground/issues/24",0.6779013,{"description":2927,"labels":2928,"number":2938,"owner":2857,"repository":2857,"state":2882,"title":2939,"updated_at":2940,"url":2941,"score":2942},"So. We're making a new major. \r\n\r\n\r\n\r\n\r\n\r\n## Goals\r\n\r\n- **More ergonomic API for creating procedures** and building out your backend\r\n- **CMD+Click** from your frontend and jump straight into the backend procedure. This will work with `react-query` as well!\r\n- **Better scaling** than the current structure - the TypeScript server starts choking a bit when you get close to 100 procedures in your backend\r\n- **Fully backward compatible** for the 99% use-case with a migration path which you can do incrementally. \r\n\r\n\r\n## Todos\r\n\r\n> **Important for contributors:** All of the work here is related to the [`next`](https://github.com/trpc/trpc/tree/next) branch.\r\n\r\n\r\nTracked in https://github.com/orgs/trpc/projects/1\r\n\r\n- [x] New Router API\r\n - [x] Tracked in [trpc/v10-playground](https://github.com/trpc/v10-playground) - the current winning proposal is https://github.com/trpc/v10-playground/pull/33\r\n - [x] Error formatting in new API - [`formatError()`](https://trpc.io/docs/error-formatting)-equivalent. \r\n - [x] `meta`-equivalent\r\n - [x] Maybe we need a `createRootRouter()` that additionally accepts `{ transformer: X, formatError: Y}`\r\n - [x] Implement new API in tRPC\r\n - [x] Make old routers compatible (`.legacy()` at the end to transform them to the new version)\r\n- [x] New client API with backward compatibility \r\n - Maybe old can be `client.query('postById', input, options)` whilst new stuff can be `client.queries.postById({ input, ...options})`\r\n- [x] New react-query API with backward compat\r\n- [ ] Make actual issues for all of these\r\n- [x] Add all old projects in a folder (copy/paste `examples/*` to `examples/.test` so we can track breaking changes easily and make sure we remain backward compatible for a long time\r\n- [ ] Rewrite `TRPCClient` to be functional instead of a class but reuse the same interface\r\n- [ ] Write a migration guide\r\n - [ ] New router API\r\n - [ ] New links\r\n- [x] Move transformers back to `runtime` to make it backward compatible\r\n- [ ] Explore: Add [`stripInternal`](https://www.typescriptlang.org/tsconfig#stripInternal)-flag\r\n- [x] Simplify HTTP-responses\r\n- [x] New links architecture (#1366)\r\n- [ ] Refactor observables implementation to have `unknown` errors or make it guaranteed to be `TRPCClientError` of some sort. \r\n- [ ] Make transformers dynamically opt-in similar to how a batch request is indicated by `?batch=1` maybe a transformed request could be `?transform=1` or `transform=TRANSFORMER_NAME`?\r\n- [ ] Write a blog post about new major and API.\r\n- [ ] \"Marketing\"? Hype video, new website, etc\r\n- [ ] Decide on structure for react-query integration\r\n- [ ] Add old website on `www/`-docs as `v9.trpc.io`\r\n - [ ] Link it in Docusaurus\r\n - [ ] Make sure we have deployment for a \"v9\"-branch\r\n\r\n### Stretch\r\n\r\n- [ ] Add DTO for clients without transformers - #1694\r\n- [x] #1597\r\n- [x] New Subscriptions API (nice to have) - #1596 \r\n- [ ] `trpc.output.snapshot()` https://github.com/trpc/trpc/issues/3435\r\n\r\n\r\n\r\n\r\n\r\n\u003Cdetails>\u003Csummary>Old notes\u003C/summary>\r\n\r\n## Definite\r\n\r\n- [x] Remove official support for node `12.x`\r\n - [x] Remove E2E-test for 12.x\r\n - [x] Change `tsconfig` build target\r\n- [ ] Add official support for node `16.x`\r\n- [ ] Add `stripInternal`-flag\r\n- [x] Remove all `@deprecated` stuff\r\n - [x] Remove `LegacyRouter` introduced in #915\r\n - [ ] [...]\r\n- [x] New links architecture (#1366)\r\n- [ ] Move official support for `react-query` `3` to `4`\r\n- [ ] Simplify HTTP-responses\r\n - [ ] From `{ id:null, result: {type: 'data', data: x } }` -> `{ result: { data: x } }`\r\n - [ ] maybe remove `id: null` from HTTP responses?\r\n- [ ] Migration guides for all changed parts\r\n - [ ] New Links\r\n\r\n\r\n## Maybe ❓ \r\n\r\n> Feedback please!\r\n\r\n\r\n- [x] Optimize so router inference only needs to be done once? #1218 \r\n- [ ] ~Update so procedures needs to return `{ data: x }` instead of just `x` so we could add metadata and potentially discriminated union of `{ data: x } | { error: y }` ~\r\n- [x] Decide: \r\n - Pipe-based rather than object resolvers? `{ input: z.string(), resolve({input}) {}}` -> `t.pipe(t.input(z.string), ({input}) => \r\n - Chained resolvers\r\n- [x] Plan how to deal with degrading typescript performance when approaching ~100 procedures (there are no runtime issues, but the DX slows down) \r\n- [ ] Turn `client.query` result into `[ output, { meta } ]`\r\n- [ ] New `useQuery()` API that expects suspense as default - See this gist: https://gist.github.com/KATT/aa1ad532d6e57520b942f657569e1505\r\n- [ ] Refactor `@trpc/server` to easier work with CloudFlare-workers etc (#1375)\r\n- [ ] Collaborate with Blitz.js? https://github.com/blitz-js/blitz/discussions/3083#discussioncomment-1841427\r\n- [ ] https://jsonapi.org/format/\r\n\r\n### Transformers\r\n\r\n- [x] Turn transformers into a link on the client (#1366)\r\n- [ ] Revert above and put transformers back to runtime 😬 \r\n- [ ] ~Turn transformers into a middleware on the server~\r\n- [ ] Make transformers dynamically opt-in similar to how a batch request is indicated by `?batch=1` maybe a transformed request could be `?transform=1` or `transform=TRANSFORMER_NAME`?\r\n\r\n### Misc\r\n\r\n- [ ] Rename `@trpc/react/ssg` -> `@trpc/react/ssr` & `createSSGHelpers` -> `createServerSideHelpers` (or something, as it is often used in `getServerSideProps()` as well as `getStaticProps()`)\r\n\r\n## Open questions\r\n\r\n- Should we continue to follow OpenRPC?\r\n- Any changes that could make tRPC easier to support stuff like Svelte/Vue?\r\n- Any changes that could make tRPC stricter support stuff like AWS Lambdas? (Already is doable to do Lambdas but through an Express->Lambda converter) #882 \r\n- Ideas?\r\n\r\n\r\n\r\n\u003C/details>",[2929,2932,2935],{"name":2930,"color":2931},"🙏 review please","A7356F",{"name":2933,"color":2934},"💸 Get paid!","c2e0c6",{"name":2936,"color":2937},"next-major/definite","5319E7",887,"[RFC] Next major overview","2022-12-19T22:11:47Z","https://github.com/trpc/trpc/issues/887",0.6784834,{"description":2944,"labels":2945,"number":2949,"owner":2857,"repository":2857,"state":2882,"title":2950,"updated_at":2951,"url":2952,"score":2953},"## Problem\r\n\r\nCurrently, it's possible to use the old client APIs to call the new ways of defining routers and procedures and the other way around. This creates quite a heavy load on TypeScript performance as we flatten all procedures on the router, whether it's used or not.\r\n\r\nSeeing that we are stepping away from string literals, this is an undesirable bottleneck & makes tRPC slower.\r\n\r\n## Proposed solution\r\n\r\n- Procedures defined with old way (i.e. `trpc.router().query('oldProc', { resolve: () => '..' )`) should **not** be callable through a proxy, and **only** with the legacy string literals\r\n- Procedures defined with new way, (i.e. `t.router({ newProc: t.query(() => '..') })`), should not be callable **except through a proxy**\r\n\r\n## Implications\r\n\r\n- Proxy will be the only way to call things in the default tRPC clients\r\n- People who want to support environments [which can't support `Proxy`](https://caniuse.com/#search=Proxy) will need another tRPC client *(TBD if we make one of those ourselves)*\r\n- We need to change the way we define interop mode on the client\r\n- We will deprecate `createTRPCClient` & `createReactQueryHooks` in favor of proxy-based APIs\r\n- We will need to define interop clients or make the current clients automatically expose a `.proxy` object\r\n- This **should not** make incremental migration from v9->v10 harder\r\n\r\n\r\n## Proposed APIs\r\n\r\nGiven the following backend:\r\n\r\n```ts\r\nconst t = initTRPC()();\r\nconst legacyRouter = trpc\r\n .router()\r\n .query('legacyProc', {\r\n input: z.string().optional(),\r\n resolve({ input }) {\r\n return `hello ${input ?? 'world'}`;\r\n },\r\n })\r\nconst newAppRouter = t.router({\r\n newProc: t.procedure.query(() => \"I am just a test, I don't know! \"),\r\n});\r\nconst appRouter = t.mergeRouters(legacyRouter.interop(), newAppRouter);\r\n```\r\n\r\n### `@trpc/client`\r\n\r\n**New way of creating a client:**\r\n```ts\r\n// Create new client\r\nconst client = createTRPCProxyClient\u003CAppRouter>({ \r\n url: 'http://localhost:3001',\r\n})\r\n\r\n// Usage:\r\nclient.newProc.query();\r\n```\r\n\r\n**Interop:**\r\n\r\n```ts\r\n// Will show deprecation error\r\nconst client = createTRPCClient\u003CAppRouter>({\r\n url: 'http://localhost:3001',\r\n})\r\n\r\n// Expose a proxy prop automatically:\r\nconst proxy = client.proxy;\r\n\r\n// ✅ These calls will work\r\nproxy.newProc.query();\r\nclient.query('legacyProc');\r\n\r\n// ❌ These will now show TypeScript error\r\nproxy.legacyProc.query();\r\nclient.query('newProc');\r\n```\r\n\r\n### `@trpc/react`\r\n\r\n**New default way of creating a client:**\r\n\r\n```tsx\r\nconst trpc = createTRPCReact\u003CAppRouter>();\r\n\r\n// Calls:\r\ntrpc.newProc.useQuery();\r\n```\r\n\r\n**Interop:**\r\n\r\n```tsx\r\nconst trpc = createReactQueryHooks\u003CAppRouter>();\r\n\r\nconst proxy = trpc.proxy;\r\n\r\n// ✅ These calls will work\r\nproxy.newProc.useQuery();\r\ntrpc.useQuery(['legacyProc']);\r\n\r\n// ❌ These will now show TypeScript error\r\nproxy.legacyProc.useQuery();\r\ntrpc.useQuery(['newProc']);\r\n```\r\n",[2946],{"name":2947,"color":2948},"RFC","78B062",2311,"[v10] Make interop non-proxy string literals & and new proxy calls mutually exclusive","2022-10-04T00:18:25Z","https://github.com/trpc/trpc/issues/2311",0.6832566,{"description":2955,"labels":2956,"number":2961,"owner":2857,"repository":2857,"state":2882,"title":2962,"updated_at":2963,"url":2964,"score":2965},"### Describe the feature you'd like to request\r\n\r\nAdd a simpler alternative way to define procedures.\r\n\r\n\r\nThis is the current way of doing it:\r\n\r\n```ts\r\nimport { publicProcedure, router } from './trpc';\r\nimport { z } from 'zod';\r\n \r\nexport const appRouter = router({\r\n hello: publicProcedure\r\n .input(\r\n z\r\n .object({\r\n text: z.string(),\r\n })\r\n .optional(),\r\n )\r\n .query(({ input }) => {\r\n return {\r\n greeting: `hello ${input?.text ?? 'world'}`,\r\n };\r\n }),\r\n});\r\n\r\n```\r\n\r\n### Describe the solution you'd like to see\r\n\r\nMost of the time, I use some sort of base procedure that does all the authz/authn, and end up just doing `.input(x).query(() => { /*...*/} )` etc at the end.\r\n\r\nHere I'm proposing to **adding** an alternative way of defining procedures that I think is a bit more readable:\r\n\r\n```ts\r\nimport { publicProcedure, router } from './trpc';\r\nimport { z } from 'zod';\r\n\r\nexport const appRouter = router({\r\n hello: publicProcedure.query({\r\n input: z\r\n .object({\r\n text: z.string(),\r\n })\r\n .optional(),\r\n resolve({ input }) {\r\n return {\r\n greeting: `hello ${input?.text ?? 'world'}`,\r\n };\r\n },\r\n }),\r\n});\r\n```\r\n\r\n### Desribe alternate solutions\r\n\r\n- There's maybe some alternative way of addressing this\r\n- This is very much a nice-to-have. \r\n- Maybe it can be a bit misleading to have two ways of doing things\r\n\r\n### Additional information\r\n\r\n- Related: #2940\r\n- `input` should not be required\r\n- Needs to work when the base procedures have existing input parsers\r\n- If someone wants to pick this up, I'll happily provide a test suite to work against\r\n\r\n### 👨👧👦 Contributing\r\n\r\n- [X] 🙋♂️ Yes, I'd be down to file a PR implementing this feature!",[2957,2960],{"name":2958,"color":2959},"@trpc/server","9BE78E",{"name":2947,"color":2948},2975,"feat: Add alternative way to create procedures","2022-10-13T13:29:56Z","https://github.com/trpc/trpc/issues/2975",0.68692523,["Reactive",2967],{},["Set"],["ShallowReactive",2970],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$fGJJInLjsxadtRuT-58PqSZdmQSKTXf6SAROTds2oWIo":-1},"/trpc/trpc-openapi/68"]