4 ms·
I wrote the initial proof of concept for tRPC a little over a year ago (though I'm no longer involved in the project). Seems like there's some confusion about h
by colinmcd 4y ago
I wrote the initial proof of concept for tRPC a little over a year ago (though I'm no longer involved in the project). Seems like there's some confusion about how this works. A more complete description is available here[0] below but I'll put a brief explanation below as well.
- It's designed specifically for a full-stack TypeScript app. Your API is implemented as strongly typed server-side functions.
- The input type is specified using a schema library like Zod or io-ts.
- TypeScript infers the return type of these functions.
- You can then import the type signatures of your functions into your client. Just types, no runtime code! This is safe in typescript with the `import type` syntax. tRPC uses those type signatures to provide a typesafe client API, basically an SDK for your API. There's no codegen happening - the client uses TypeScript generics to provide a set of strongly typed "proxy functions" that can be "called" on the client. These proxy functions execute HTTPs requests under the hood: https://trpc.io/docs/rpc https://trpc.io/docs/rpc
The point is to avoid the boilerplate, codegen, and lack of DRYness associated with building a strongly typed API in TypeScript. You can do this with GraphQL but it relies on code-generation, requires complete buy-in, and (IMO) doesn't provide a great developer experience. TypeScript has a native way of representing types, so the goal is to avoid an intermediate representation (in the form of an OpenAPI spec or GraphQL schema) entirely. As you update your server code, the client's type signatures update instantaneously.
Another important goal is to make it easy to write DRY code when building APIs. Without tRPC, it's common to manually provide type definitions for the results of API calls. But those definitions can easily get out of sync with your actual server code. tRPC infers types from your code itself and provides a typed interface for your API thats doesn't require any manual type annotations.
[0] https://colinhacks.com/essays/painless-typesafety https://colinhacks.com/essays/painless-typesafety
- oneplane 4y agoSo essentially, it's protobuf but it describes the API instead of a message (which arguably is also an API description) and is for TypeScript on both sides.
- colinmcd 4y agoExactly. But with faster iteration speed, more type inference, less overhead, and a TypeScript-native DX.
- lalaithion 4y agoWhat's the backwards compatibility story here? What changes to backend function argument and return types can I make without breaking currently-open webpages when I push a new backend instance?
- codethief 4y agoThis is very cool, thanks so much for explaining how this works and, of course, for initiating such a cool project! As far as I can tell, tRPC basically bridges (hides) network communication and allows doing remote procedure calls almost like regular, type-safe function calls on the same machine within the same process. Now I would give a fortune for having something like that also for cross-language communication and for communicating with other processes (binaries and shell scripts). I've been thinking about this a lot in recent years: In SWE we need to jump through many hoops only because it's so god damn hard to invoke a function or a whole API living somewhere else in a type-safe manner. Intermediate formats like JSON, protobuf, standards like REST, OpenAPI, and GraphQL, and even languages like SQL (and the various ORM libraries it inspired) are all a result of that to some degree: Once data leaves the safe haven of your (hopefully statically typed) programming language where the compiler/interpreter knows exactly what its type is and what the signature of the function is that you're trying to call, you're basically on your own. I recently read about WASM Interface Types[0] and it seems like a step in the right direction, though unfortunately it will only bridge the – let's call it – type safety gap between processes, not between different machines in a network. [0]: https://hacks.mozilla.org/2019/08/webassembly-interface-types/ https://hacks.mozilla.org/2019/08/webassembly-interface-type...