青木
青木2y ago

How are they defined separately?

I am using monorepo for my project design and I want to separate the definition of trpc completely independently. I have @app/api to take care of implementing the trpc api definitions in @app/api-define. I want to define all trpc api content ( type define ) in @app/api-define as a separate package. Then I just need to use @app/api-define in @api/next-app. As a standalone package, I can even use it in a different project, or convert it to an rpc specification that other languages will recognize.
21 Replies
Nick
Nick2y ago
tRPC doesn’t really work that way, the types come from the implementation, as opposed to OO-land where the implementation is often built on predesigned interfaces It’s not an anti-pattern here to just “import type from” the api directly from the client, you won’t bundle the entire API into your frontend if you do it right
青木
青木OP2y ago
import type from is also an imported type, why can't it be alone?
Nick
Nick2y ago
Not sure I understand what you mean
青木
青木OP2y ago
import type from somebody Import types only, and will not contain code
Nick
Nick2y ago
Yes, the client only needs the types from the API
青木
青木OP2y ago
So, can I declare my own AppRouter for trpc? Do not use export type AppRouter = typeof appRouter;
Nick
Nick2y ago
You might want to take a look at the example projects and see how the maintainers structure this stuff, the recommended patterns are quite consistent
青木
青木OP2y ago
I have to import type from my backend code, and I can't distribute GraphQL Schema files like GraphQ L does.
Nick
Nick2y ago
Yes, that’s correct. You could publish the typescript types as a npm package but the batteries aren’t included there. trpc is designed for co-located client/server code first
青木
青木OP2y ago
So I'm looking for a solution, if the client of trpc only needs one type file, can I define it manually?
julius
julius2y ago
hey, don't completely understand the goal of what you're trying to do - have you checked out https://github.com/t3-oss/create-t3-turbo ?
GitHub
GitHub - t3-oss/create-t3-turbo: Clean and simple starter repo usin...
Clean and simple starter repo using the T3 Stack along with Expo React Native - GitHub - t3-oss/create-t3-turbo: Clean and simple starter repo using the T3 Stack along with Expo React Native
julius
julius2y ago
there, we have our api package which exports the router and it's type: https://github.com/t3-oss/create-t3-turbo/blob/main/packages/api/index.ts and the nextjs api handler can import the router: https://github.com/t3-oss/create-t3-turbo/blob/main/apps/nextjs/src/pages/api/trpc/%5Btrpc%5D.ts and to create the hooks, we just need the types: https://github.com/t3-oss/create-t3-turbo/blob/29d207dc197454dd0a5b8b18287f9594e2cdfa53/apps/nextjs/src/utils/api.ts#L5 and then for apps which aren't serving the router but just consuming the api, they also just need the types: https://github.com/t3-oss/create-t3-turbo/blob/597ec9861a3da0ac9e631b9a240420b62e89253b/apps/testy/client.ts#L2 but i dont understand why you want the type in a separate package?
青木
青木OP2y ago
I checked the code inside, not what I want I need trpc to be split into type definition and implementation, not merged together. It is still together in t3, it is difficult for me to encapsulate the framework belonging to our company based on trpc. In the way of importing types (import type from tsrpc_api), once some other code on the server is imported in my code, it will be packaged into the front-end project. I even need to write some tools for security inspections.
青木
青木OP2y ago
I generally use https://nx.dev for project design. I write an API it should be an app rather than library.
Nx
Nx: Smart, Fast and Extensible Build System
Nx is a smart, fast and extensible build system which comes with first class monorepo support and powerful integrations.
Nick
Nick2y ago
It won’t be packaged into the project, I also use Nx and importing by type will not cause your whole backend to be bundled This was the second thing I said Types are stripped at compile time and all imports via type imports will get dropped and tree-shaken
青木
青木OP2y ago
but in nx, api should be an application, and the application does not import aliases It can be set manually but I prefer to separate them. One of our projects has a lot of developers involved and I need to write some checks to make sure all are obeying using type imports, which can be a disaster if someone forgets. my doubt is that for trpc, only the type definition is required when creating the client. Why is this type definition forced to be written together with the server instead of separate?
Nick
Nick2y ago
Nx can ban imports of projects via eslint, in-fact you would have to disable this in order to import the api because it’s an application. So you can just disable for the one line in your client which is allowed to import it, then re-export and force everyone else to import from that file Ultimately if you don’t trust this stuff then you probably chose the wrong solution for your backend.
julius
julius2y ago
If someone imports appRouter instead of type AppRouter your app will blow up and not run - since you’d be importing server code on the client - you would get errors which is quite easy to test against. Alternatively you can restrict imports with lint rules as Nick suggests
Captain
Captain2y ago
im also using nx as a monorepo workspace. what u need to do i create a node library wheren ur trpc definitions and routes go. in your next app, the trpc utils for batching and stuff like that go in the uitls folder at the same level as your next app it took me a while to figure this out. trpc is not a stand alone app. in NX apps cant share types/code but libs can this my nx graph
Captain
Captain2y ago
Captain
Captain2y ago
business-data-access and shared-data-access are both node libraries business-data-access implements a node library which has all the routes for the nextjs business app. shared-data-access exports shared code for all applications. such a context. but also auth. since this workspace will have two applications and both will have the same logic also important to note is, smart components need to live in your next app. and dumb components that do not have access to data can be exported from a library the reason for this is that the trpc utils folders lives inside your nextjs src folder. and sadly apps cant share code

Did you find this page helpful?