I heard from one developer that is senior that GraphQL create more issues or maybe he meant more job than it should be, so he wrote me this [google translated]: "REST, CRUD and wio. Fastify is cool because it handles requests very quickly and you can go crazy with plugins. Plus some ORM, like Prisma or TypeORM and MonoRepo terminology for the whole thing. NX is nice for embracing such things from the automatic."
Please try not to be too judgmental or arrogant about "your way". Kotlin is anything but a "dated way". And I say this as a dev who works with both (and also with GraphQL). Kotlin multiplatform can do much more and more effectively than what node/Typescript can do and I'd say that the language itself (Kotlin) is better too in many aspects. I use Typescript and node every day, and I like the tech, but calling Kotlin, Flutter or whaterver contemporary technology a "dated way" is not only plain arrogant, but it also says much about the knowledge of the person who says it.
I've been looking into Kotlin for building APIs, but I like to make them type-safe. Is there a good way to make one in Kotlin? I know you can write a bunch of boilerplate annotations to document your API using OpenAPI, but I think it's better to generate it from the API code itself, e.g. from the controller methods and I haven't seen a robust way to do that in Kotlin.
@@eltyo340 You could re-write Apache Kafka, Apache Cassandra, Apache Spark in Kotlin, but trying to do that in TypeScript while achieving the same performance would be very difficult, if not impossible.
A lot of the time people think that graphql is going to automatically improve the performance. Graphql is what you described, 'schema' language. If you use graphql as a backend for frontend your graphql becomes extremely chatty. We had issues with port exhaustion after we deployed the graphql server as a serverless function. Graphql only improves performance if you design nested schema efficiently
If the backend is a monolith, it doesn't need to be chatty (e.g. you can use a prisma plugin or roll your own solution to optimized based on the graphqlinfo arg). Even using the data loader pattern with a monolithic graph but disparate backing services manages chattyness sufficiently. More importantly any chatty-ness is encapsulated by the backend and not directly exposed to the front-end. Latency is latency and if the backend has to talk to 20 services to give a response, that problem doesn't evaporate by using tRPC
If trpc is just "calling a function on the backend". How is it different than just a rest api? Usually a rest endpoint is a function that does something to the backend. Or retrieves something from the backend. Isn't that just "calling a function on the backend".
We are adopting GraphQL in our company without almost no guidance or expertise, and I have to say - people just don't get it and it's getting messy really fast. And it sucks because the ideas of it is great, but for some reason people have a hard time making the correct mind shift and design the schema well
Probably tRPC is the future, because it’s great, but at the moment GraphQL is more in demand by companies, looking at the job offers. For the moment it is "worthwhile" to learn GraphQL first and well, then tRPC ✌🏻
2:38 "tRPC is bringing them closer together" i.e. Tight Coupling. RPC approaches work best when the same team controls the client and the endpoint. That way keeping them in sync isn't a problem. In any other situation it's only a matter of time until the downsides of tight coupling are going to make themselves known. The other issue is that RPC shouldn't be used when the response tends to be high latency and/or will quite commonly fail because a successful result depends on multiple back-end services collaborating successfully. With RPC you still have to be careful that the granularity of interaction isn't too fine otherwise your app's chattiness could easily become a problem under less than idea network conditions. This isn't meant as an endorsement of GraphQL.
@Peer Reynders they're still 2 separate process so from an ops perspective, you have to treat your trpc surface as an accreting API and deploy your backend first or things will break (whether that short-lived breakage is acceptable is entirely domain-dependent and should not be assumed to be safe)
I've used GQL with federation for 2 years now. It feels nice to be able to create super flexible queries that fetch data from many different microservices with one query from frontend. Would love to see some more complex examples of tRPC to understand why it's good and what it's advantages are over GQL. My current impression is that tRPC has less boilerplate code since there's no need to write both the schema and resolvers - with tRPC, you just need the resolver. I haven't really cared about this since the schema is generally pretty trivial to write out but l agree that the less you can get away with, the better. I would like to see an example of tRPC where backend (which could be multiple microservices) and frontend are in different repos but I'm guessing you would have to do `import type` and be careful you don't actually import backend code into frontend. As for the perks of GQL, I like the flexibility it gives on frontend. It's easy to write out a single query that queries multiple microservices. I would need to see how that's done with tRPC or traditional REST APIs. My impression is that frontend would need a lot of back and forth calls to get the required data when it needs to call a lot of different microservices while with GQL, Apollo Gateway does a lot of the magic for you. Some of our microservices are also Java/Kotlin so GQL definitely benefits us here.
Would you say that GQL is more appropriate for building a large database API where different users want to fetch different fields? I imagine that using a more RESTish solution for this would result in having multiple permutations of fields. I personally find that the biggest benefit for GQL, but I don't hear a lot of people saying this. Also, when you described the microservices use-case, would you use multiple repos with semver in your package.json or one big repo for all?
@@galer7 Each microservice is in its own repo. They all contribute a "subgraph". The apollo gateway is its own microservice which knows about all the other microservices and stiches all their subgraphs into one supergraph/schema. Frontend then fetches the schema from the gateway service to generate its types and make queries/mutations. GQL letting you avoid over fetching is nice but I recall some people saying tRPC lets you do it easily with Prisma. One of these days when I'm not lazy, I really need to take at that stack. That said there are some things with GQL we needed to be wary of. Authorization needs to be done at an entity level so you don't accidentally let a user see confidential info by querying for blogPost.createdBy.password or something similar. GQL is also a null first language but we didn't have a nice way of checking for nulls everywhere on frontend so we started marking fields as non-nullable a lot. We eventually realized that it's best to leave federated entities as nullable so when a small error in one microservice fails, your big query that fetched useful info from other microservices doesn't completely die so your frontend component can still show partial data.
I worked for a startup that loved keeping frontend and backend teams separate, and none of the backend engineers knew how to make a good REST API, so they grabbed gRPC and proceeded to create ridiculously complex ways of saving and retrieving data. Endpoints had weird side-effects and things like pagination were treated like crazy features nobody expected. There's a reason REST was invented and took off like crazy. Web development was more like RPC before REST came along. I don't know if there's value in RPC above REST, but I'm strongly biased against it because of that experience.
I mean, correct me if i am wrong here, but every get/put/post etc is handled by a function in the backend that takes the params from the URL or body as its param. Knowing that, tRPC is just cutting the middle man and letting you just call that function from the frontend and I think you could maintain (for legacy purposes) both mechanism. What was the problem with gRPC exactly?
@@MarkVonBaldi I didn't say it was a technical problem. I said some engineers can use it to bypass learning how to make good endpoints for managing resources. It can be a crutch.
Can you use tRPC when the front end is separate from the backend? What is the solution if the front is a react app that calls apis on a separate rails server?
I'm kinda confused by you saying that kotlin is "dated way" and it should be replaced by typescript. Also for the backend, JVM languages are just more comfortable to work with. Dynamic one, even with type system placed ontop, would probably never be as structured and well-though unless you do it from scratch.
So, if trpc is a single API route, can I call it in a Flutter app (just for example), or any other non TypeScript application, and get the data? Or is it that since trpc does not return JSON, I will be unable to do this?
Thanks for this great video Theo, this has answered a lot of my questions and really breaks down the unknowns and presents them in an easy to understand way!
This would be an interesting video for me since I am an average GQL enjoyer but am open to alternatives. But I immediately clicked off when your firsts words were “you need to have TS on the frontend and backend.” It’s just not feasible to tell all API consumers that they have to use TS.
So tRPC is better than protobufs only if the client and server code are in the same repo, is my understanding correct? I'm sure we can use protobufs to generate client code.
Love your content! I've used GQL only twice and I feel like I can agree with "REST with more steps" I'm going to try tRPC after I graduate from bootcamp. The bootcamp I'm in requires us to use Rails as our backend
I started using openapi-trpc a couple weeks ago and it is really the best of both worlds. I had some issues related to "complex" nested types, but I managed to find a way around it (so far). Also, you can later go from open-api to protobuffs and use those types in other languages. 100% recommended, Give it a try!!
yes, but TS people clearly like to lock themselves in the worst way possible so that they can use even more JS/TS. If any of these companies one day can't use TS/JS on the backend for whatever reason anymore, they are basically screwed and can do a full rewrite front to back.
My users and managers care very little about backend, plus it is recurring cost and exponentially growing complexity. Stateful backends so easily become cupboards of horror! I'm going to watch, optimistic tRPC can be used ti mitigate some of those negatives.
It would be cool to write a plugin for Next/Nuxt/Sveltekit so you could include your backend actions in components. So you could specify backend methods the same way you currently specify frontend methods. Even cooler if it could work with FaaS and hot-deploy both ends whenever you save your component source.
How do you handle versioning with tRPC? We usually deploy the back-end and front-end at different times and prefer to have a small window of backwards compatibility between the two.
Treat it as an accreting API for the duration of any deployment -- give the new implementation a different name, preserving the original implementation at the original name. Once you confirm all clients are using the latest version, push a breaking change that makes the old name have the new logic, and have clients use the old name. Once you confirm all clients are using the latest version, remove the new name. Basically the same way you do a breaking db schema change without deploying a distributed monolith. Watch Rich Hickey's talk on how semver is broken for more on the concept of accreting APIs
with all the problems and anti-patterns that typescript has, using another language for backend is not a dumb idea. With highly distributed enterprise scale service ecosystems trpc won't work that well in my opinion. I personally don't enjoy coding in typescript. Golang is much more pleasant I think. Also a question, in cases where graphql is not necessary, can protobufs be used instead of trpc?
It kind of feels like we are going back to the past. As if we noticed how stupid we were for wanting to change things, like CSR to SSR/SSG (although we now have hydration), or from Rest and GrapQL to RPC... I wonder if we will diverge from this again in the future. This might be like retro going back on style
i still can't get it. how can it be "the future" or "graphql killer" if it requires hard coupling frontend and backend (and omg monorepository for both), which is oblivious anti-pattern for any serious projects. Ofc it can take own place for small project, where small team is building both sides of application, but it will never kill or replace graphql or rest, until it does not have any out-of-the-box solution for projects, where frontend and backend are independent microservices
I think you've hit the nail on the head. The two biggest concerns in software design is coupling and cohesion. There's many benefits to tRPC, but the one big downside is a tightly coupled front and back end. Just depends on the project whether that tradeoff is justified.
So - if i have an app where i am bound to using python on the backend for (django), how would I get something similar to tRPC? I am currently just going to use GraphQL but is there any way to get a similar setup to T3 stack with a python backend? Is my only option for something that measures up to go typescript backend?
@@t3dotgg Gotcha, was thinking of something like mypy for pseudo type safety but thinking about it I can see how that was a silly question, asked after a night of no sleep lol
idk but I'm using graphql and I cannot define optional parameters for a resolver's input. So in the end... Lots of useless data traveling through the network.
We used JRPC an my previous company. Our back, and was written Node, then got rewritten and Go. I really like the simplicity of calling a function on the server. Any thoughts on JRPC?
This video came at a perfect time. I have been wondering about this topic for a few days now. So, in a situation where a developer is writing an entire application (frontend and backend) and has complete agency over the database, it seems like tRPC makes the most sense, right?
Does TRPC even work well with Nextjs and Vercel (serverless)? I can't do a single router for all backend queries because then all my backend code will end up in a single serverless function which is horrible for performance, infact we are going through a big refactor just to avoid that
I heard you say, 'those few use cases where typescript is very slow for your backend'. Being a junior and self taught dev, how would one differentiate between such usecases? I generally think if I have too complex data queries/ relations or the need to call my backend too many times on most of the pages, graphql is my guy. What such thinking should I apply on when to use TS or golang for a project?
Nodejs in general, regardless of using typescript or just regular JS is not really great for CPU intensive tasks. If your product is mostly just fetching data from a server or doing most stuffs like Crud operations Nodejs is still your guy. Whether you are using graphql or regular Rest Apis
east-west (service-to-service) communication is generally where you might start optimizing for performance by picking a different language. your BFF (backend for frontend) sits between clients and other services, and is an example of north-south communication. You can generally get away with using node for your BFF in the name of using the same language on your front-end and its backend and the benefits that provides (e.g. shared validation logic using something like zod). Then you would offload CPU-heavy and/or ML workloads to some other service in an appropriate language (maybe Scala, maybe golang, maybe python-wrapped-performant-C++), ideally using grpc/protobufs/etc for communicating with those sorts of services. tl;Dr if you're just doing basic CRUD on the backend, you're not likely to need to switch languages for performance reasons.
Why do you think the GitHub GraphQL API is bad? Would love to understand the criticism and see you point out the problems you see based on the experience you have
Many Backends use legacy code that can't really be touched. Frontend on the other hand is always looking for latest and greatest. Graphql helps me merged both in a single endpoint for apps.
Hello Theo. I love thé idea behind t3. Especially because all the stacks there are those I feel quite comfortable with. Given that NextJs is a Fullstack framework. If I want the next api be consumed by the mobile version developed in react native as well as the web. Is that pretty comfortable and easy?
i recently realized how graphql really just makes my life harder. it doubled my bugs, i have to fixed and refract code twice even with nexus. especillay when using it with prisma. i think i'm gonna trash graphql. i used to love it though for past few years but i finnally realized it's really not that usefull even with complex project.
I think, tRPC is goot fit for teams that mainly consists of full stack developers. graphql is more well suited for large teams that have separate devs for frontend and backend.
It really hurts to listen to this because I'm missing out so much... At my company we're using untyped, untested and undocumented Javascript Microservices with mongodb.... Everything is a mess, we never really know what data we're gonna get... I would be so happy if I'd get any sort of typesafety at all... Even it weren't perfect..
I'm the Flutter developer that won't let go of their ways lmao. Subscribed so I can refresh my knowledge for the React side of dev. Love your channel! I have already learned so much
The thing that bothers me the most with tRPC is the fact that you are selecting the query by simple string and this means no autocompletion. You can't just hit ctrl + space and see all the available queries. It can be fixed by using string-like enums but I feel that it can be solved in a better way.
This is nothing new. For example .NET's old WCF is based around this concept where you delcare an interface that serves as communcation contract. It's just creating an interface that will be implemented by your BE and then creating an object proxy on FE based on the interface. The interface's implementation becomes a controller and methods become actions with the proxy on FE serving as "smart fetch". The proxy can be generated or create at runtime using reflection. This can be generally achieved even in JS when using classes. However, this approach was eventually phased out as WCF got succeeded by ASP NET, but there are libraries that do this even for ASP NET. The tRPC seems like a downgrade as u still need to perform the tRPC call explicitly by using client.query('name', input). I think the better way to do this would be doing it as .NET did using OOP by explicitly using object (of the given interface) to perform call which would automatically map to it's implementation on the BE. You may argue that interface does not exist at runtime and thus cannot be introspected to generate routes and proxies, but you may use abstract class instead. By this FE does not have to distinguish whether the object performs HTTP calls or is just "normal" object. You may argue that there has not been anything like this in TS/JS, but I think that is generally because it died out before Node.JS was created. The benefit of joined versioning comes from the monorepor. No matter whever GraphQL, SOAP, REST etc... as long as it's a mono repo the versioning of FE and BE is joined.
@@t3dotgg One additional thing: The contract seems to be purely server-based in the current version of tRPC (declared by the BE). However there are certian situation where you might want to declare contract in FE code or even somewhere else. When using interfaces or classes they can generally be declared anywhere, even in different repos (and being shared using npm). One last thing: If ancient .NET banking software showed me anything. This approach is a good servant but a bad master as it completely kills of reusability of the API by non-compatiable languages. For example when we were building React FE, we had to create additional BE in .NET as TS cannot consume .NET interfaces and we were not brave enough to hardcode routes in the client (and other related issues like picking proper HTTP method, deciding whether put input in body or query strings etc...). In order to be a proper abstraction for communication this proprietary .NET framework did not expose anything that could be used to at least generate TS (like swagger doc, because swagger is REST specific which would limit this framework to only use REST). I think this has potential as router-and-proxy generator which can be configured for different communication protocols and scenarios (including swagger doc generator) to save time when language matches, but it should not prevent direct usage of the underlying communication protocol if necessary. So it's rather extend than replace.
I just read a article from logrocket to understand what the actual difference to gRPC is and this is what they wrote: "While tRPC is indeed also a remote procedure call framework, its goals and basis differ fundamentally from gRPC. The main goal of tRPC is to provide a simple, type-safe way to build APIs for TypeScript and JavaScript-based projects with a minimal footprint" This has to be the stupidest reason to basically build a completely new "protocol", that is not a protocol and nobody else can use. So yeah, TS/JS people are one more time too stupid to use their own tooling and now need something like this because they can't properly deal with types, even though they already have the same data representation on the front and back-end.
Is tRPC good enough for mobile apps? because one of the points graphql makes is the fetch just what you want philosophy to deal with slow, unreliable and expensive mobile data on phones.
what about unnecessary fields what will you get with query? GraphQL give me possibility to get only queried fields, also I can query two users by id with one query for example RPC needs not for communication only, this need to connect two parts of one application in network This is great solution for nextjs api part, but it's not GraphQL killer, because they cover different things
Thank you for this really good description of what tRPC is - I saw it around Twitter, but I didn't understand why it's useful. The issue of over using GraphQL is dear to my heart - I work in a large bank, and they've recommended that all BFFs default to using GraphQL. Although everyone was enthusiastic about it because it's a chance to learn a new framework, it's resulted in over-complicated codebases for very simple BFFs, and new devs struggling to understand and extend those codebases.
I’m a Kotlin Android dev that you speak of, with React Native experience. I tend to agree with the attempt to share components between React Native and React web. My personal projects are all Typescript/React and I also use React Native, but I can’t deny the dev experience with Flutter is much better. But because Typescript allows me to hit multiple birds with one stone, I deal.
As a consumer I would way rather have a GraphQL endpoint. Having singular API endpoints limits you to whatever the developer had originally intended, while crafting a good GraphQL schema can enable a much broader set of use cases outside of what was originally thought of, and avoid things like over-fetching. Really click-baity title.
@@t3dotgg I did, and to your clickbait question of "Is GraphQL DEAD??" you gave a bunch of reasons and scenarios in which GraphQL is good. Also, it's really not that hard to interact with, both for devs and consumers, but ok. And you also talked about the stricter nature of tRPC; I've never heard of or used tRPC but based on your description that's how I understood it. If I misunderstood maybe correct me instead of being a dick? But title is clickbait af regardless, hate how youtube took away dislikes number so I know clickbait content like this to stay away from
Hard agree with the point about it being easy to use GraphQL to make hell. We use GraphQL a little bit at my company but we see no perceivable benefit from it and it just makes everything much more difficult.
Im still not a tRPC user yet. But can we take type safe advantage from tRPC while our app is not monolithic? Like in real world there would be microservices, multiple frontend repo, even microfrontend, blablabla and so on. In this situation, is tRPC still a good choice?
@@oscarljimenez5717 May be it won’t be suit to my company. We separate all this for the ease of out sourcing , part time etc. it is supposed that the non full time staff won’t get the full source code. Seems Pretty hard for us to adopt it in this situation. May be next small project that we might try
Theoretically, all the tRPC client needs is the server's tRPC router type (which is the 'schema' the client will operate on, similar to how openapi clients can be generated from openapi specs). So if you find a way to publish the type as its own package, you should be able to import it with tRPC in a client app. Is it feasible? I don't know. But the cool thing is that no matter how many servers you would want to integrated with a single tRPC client, the amount of code running on the client is still the same. That's neat.
Both tRPS and GraphQL are still very inefficient because of HTTP and JSON. If we swapped HTTP with QUIC and JSON with some custom low-level and binary parser then that would be absolutely amazing.
Using tRPC in a language that isn't Typescript is literally just REST with extra steps GraphQL is the right solution if your clients are multi-language, even the creator of tRPC recommends gql for such
Your audio is -14.9 dB lower than it should be. I always have to turn up my speakers when listening to your videos and then have them blow my out of my chair when I start a new video by someone else :D.
I was critical on some stuff but great video and like I expected man when u get down to business - intelligent, great explanation. It’s like awww okay ya this is good stuff. Maybe I just caught some stream rants lol. Thanks 4tv !
I have used GraphQL with Contentful CMS, GraphCMS & FaunaDB. I don't know how tRPC will Integrate with these popular tools. Also Note that GraphQL Server Frameworks like GraphQL Yoga & GraphQL Helix & tools like Envelop, Envelop Plugins & GraphQL Tools with GraphQL Mesh & GraphQL CodeGen & more... are making GraphQL DX Awesome. Please make more explorations to current situation before going online.
tRPC will have a short lifetime. In real large companies, no one will commit themselves to a single technology. This has to do with the availability of developers, and above all that this technology is not the optimal solution in all areas. The RPC stack isn't new, and there's a reason it hasn't caught on.
I've used GrapHQL a lot of the last 4ish years and I still love using it, although, in a lot of ways, tRPC is what I hoped GraphQL would be.
That is very interesting. The question for you Tom would be: would you leave GQL for TRPC?
@@codewithguillaume Apparently, he could.
I heard from one developer that is senior that GraphQL create more issues or maybe he meant more job than it should be, so he wrote me this [google translated]:
"REST, CRUD and wio. Fastify is cool because it handles requests very quickly and you can go crazy with plugins. Plus some ORM, like Prisma or TypeORM and MonoRepo terminology for the whole thing. NX is nice for embracing such things from the automatic."
Please try not to be too judgmental or arrogant about "your way". Kotlin is anything but a "dated way". And I say this as a dev who works with both (and also with GraphQL). Kotlin multiplatform can do much more and more effectively than what node/Typescript can do and I'd say that the language itself (Kotlin) is better too in many aspects. I use Typescript and node every day, and I like the tech, but calling Kotlin, Flutter or whaterver contemporary technology a "dated way" is not only plain arrogant, but it also says much about the knowledge of the person who says it.
I've been looking into Kotlin for building APIs, but I like to make them type-safe. Is there a good way to make one in Kotlin? I know you can write a bunch of boilerplate annotations to document your API using OpenAPI, but I think it's better to generate it from the API code itself, e.g. from the controller methods and I haven't seen a robust way to do that in Kotlin.
I'm a typescript purist, but genuine question: could you explain some of the use cases where kotlin is better?
@@eltyo340 You could re-write Apache Kafka, Apache Cassandra, Apache Spark in Kotlin, but trying to do that in TypeScript while achieving the same performance would be very difficult, if not impossible.
Very accurate
It's content, it drives engagement (like your comment and mine). Nothing is meant to be taken as serious as it seems.
A lot of the time people think that graphql is going to automatically improve the performance. Graphql is what you described, 'schema' language. If you use graphql as a backend for frontend your graphql becomes extremely chatty. We had issues with port exhaustion after we deployed the graphql server as a serverless function. Graphql only improves performance if you design nested schema efficiently
If the backend is a monolith, it doesn't need to be chatty (e.g. you can use a prisma plugin or roll your own solution to optimized based on the graphqlinfo arg). Even using the data loader pattern with a monolithic graph but disparate backing services manages chattyness sufficiently. More importantly any chatty-ness is encapsulated by the backend and not directly exposed to the front-end. Latency is latency and if the backend has to talk to 20 services to give a response, that problem doesn't evaporate by using tRPC
If trpc is just "calling a function on the backend". How is it different than just a rest api?
Usually a rest endpoint is a function that does something to the backend. Or retrieves something from the backend. Isn't that just "calling a function on the backend".
We are adopting GraphQL in our company without almost no guidance or expertise, and I have to say - people just don't get it and it's getting messy really fast. And it sucks because the ideas of it is great, but for some reason people have a hard time making the correct mind shift and design the schema well
Probably tRPC is the future, because it’s great, but at the moment GraphQL is more in demand by companies, looking at the job offers. For the moment it is "worthwhile" to learn GraphQL first and well, then tRPC ✌🏻
Or you convince your company to switch
2:38 "tRPC is bringing them closer together"
i.e. Tight Coupling.
RPC approaches work best when the same team controls the client and the endpoint. That way keeping them in sync isn't a problem. In any other situation it's only a matter of time until the downsides of tight coupling are going to make themselves known.
The other issue is that RPC shouldn't be used when the response tends to be high latency and/or will quite commonly fail because a successful result depends on multiple back-end services collaborating successfully.
With RPC you still have to be careful that the granularity of interaction isn't too fine otherwise your app's chattiness could easily become a problem under less than idea network conditions.
This isn't meant as an endorsement of GraphQL.
Nah, Deepkit RPC is the future.
@Peer Reynders they're still 2 separate process so from an ops perspective, you have to treat your trpc surface as an accreting API and deploy your backend first or things will break (whether that short-lived breakage is acceptable is entirely domain-dependent and should not be assumed to be safe)
I've used GQL with federation for 2 years now. It feels nice to be able to create super flexible queries that fetch data from many different microservices with one query from frontend. Would love to see some more complex examples of tRPC to understand why it's good and what it's advantages are over GQL.
My current impression is that tRPC has less boilerplate code since there's no need to write both the schema and resolvers - with tRPC, you just need the resolver. I haven't really cared about this since the schema is generally pretty trivial to write out but l agree that the less you can get away with, the better. I would like to see an example of tRPC where backend (which could be multiple microservices) and frontend are in different repos but I'm guessing you would have to do `import type` and be careful you don't actually import backend code into frontend.
As for the perks of GQL, I like the flexibility it gives on frontend. It's easy to write out a single query that queries multiple microservices. I would need to see how that's done with tRPC or traditional REST APIs. My impression is that frontend would need a lot of back and forth calls to get the required data when it needs to call a lot of different microservices while with GQL, Apollo Gateway does a lot of the magic for you. Some of our microservices are also Java/Kotlin so GQL definitely benefits us here.
Would you say that GQL is more appropriate for building a large database API where different users want to fetch different fields? I imagine that using a more RESTish solution for this would result in having multiple permutations of fields. I personally find that the biggest benefit for GQL, but I don't hear a lot of people saying this.
Also, when you described the microservices use-case, would you use multiple repos with semver in your package.json or one big repo for all?
@@galer7 Each microservice is in its own repo. They all contribute a "subgraph". The apollo gateway is its own microservice which knows about all the other microservices and stiches all their subgraphs into one supergraph/schema. Frontend then fetches the schema from the gateway service to generate its types and make queries/mutations.
GQL letting you avoid over fetching is nice but I recall some people saying tRPC lets you do it easily with Prisma. One of these days when I'm not lazy, I really need to take at that stack.
That said there are some things with GQL we needed to be wary of. Authorization needs to be done at an entity level so you don't accidentally let a user see confidential info by querying for blogPost.createdBy.password or something similar.
GQL is also a null first language but we didn't have a nice way of checking for nulls everywhere on frontend so we started marking fields as non-nullable a lot. We eventually realized that it's best to leave federated entities as nullable so when a small error in one microservice fails, your big query that fetched useful info from other microservices doesn't completely die so your frontend component can still show partial data.
You nailed. Saying truck is better means you are using graphql for the wrong reason
6:58 Thanks for the shout-out Theo! :)
I worked for a startup that loved keeping frontend and backend teams separate, and none of the backend engineers knew how to make a good REST API, so they grabbed gRPC and proceeded to create ridiculously complex ways of saving and retrieving data. Endpoints had weird side-effects and things like pagination were treated like crazy features nobody expected. There's a reason REST was invented and took off like crazy. Web development was more like RPC before REST came along. I don't know if there's value in RPC above REST, but I'm strongly biased against it because of that experience.
I mean, correct me if i am wrong here, but every get/put/post etc is handled by a function in the backend that takes the params from the URL or body as its param. Knowing that, tRPC is just cutting the middle man and letting you just call that function from the frontend and I think you could maintain (for legacy purposes) both mechanism. What was the problem with gRPC exactly?
@@MarkVonBaldi I didn't say it was a technical problem. I said some engineers can use it to bypass learning how to make good endpoints for managing resources. It can be a crutch.
@@mfpears I suppose so.
@@MarkVonBaldi +1 will definitely happen
Can you use tRPC when the front end is separate from the backend? What is the solution if the front is a react app that calls apis on a separate rails server?
What do you think about REST with openapi/swagger schema to have that contract between a backend and frontend?
You can use Hasura, which creates a GraphQL endpoint out of the box without any effort.
I'm kinda confused by you saying that kotlin is "dated way" and it should be replaced by typescript. Also for the backend, JVM languages are just more comfortable to work with. Dynamic one, even with type system placed ontop, would probably never be as structured and well-though unless you do it from scratch.
I'm confused. What does tRPC do that I don't get from a rest API and something like openapi-typescript to generate frontend types?
So, if trpc is a single API route, can I call it in a Flutter app (just for example), or any other non TypeScript application, and get the data? Or is it that since trpc does not return JSON, I will be unable to do this?
U will surely be unable
Thanks for this great video Theo, this has answered a lot of my questions and really breaks down the unknowns and presents them in an easy to understand way!
why not use strapi for GQL?
anyone remember when rendering engines where a thing ( stuff like handlebars and thymeleaf ), React is a blessing (especially if you use TS)
Can you use tRPC with a graph database like neo4j
This would be an interesting video for me since I am an average GQL enjoyer but am open to alternatives. But I immediately clicked off when your firsts words were “you need to have TS on the frontend and backend.” It’s just not feasible to tell all API consumers that they have to use TS.
So tRPC is better than protobufs only if the client and server code are in the same repo, is my understanding correct? I'm sure we can use protobufs to generate client code.
had a question: is trpc a RPC framework? I know we get fullstack typesafety but do we get protobuff levels of speed?
RPC does not imply protobuf, it’s just “remote procedure calls”. So no, this is slightly slower than normal REST (it uses SuperJSON)
@@t3dotgg thanks;)
Procedures that by definition don't return values or results call functions that return both...
Love your content! I've used GQL only twice and I feel like I can agree with "REST with more steps" I'm going to try tRPC after I graduate from bootcamp. The bootcamp I'm in requires us to use Rails as our backend
What bootcamp is it? I know AA used to have Ruby and Rails in their curriculum but they now change to Python. Both old and new curriculum have Node
I started using openapi-trpc a couple weeks ago and it is really the best of both worlds. I had some issues related to "complex" nested types, but I managed to find a way around it (so far). Also, you can later go from open-api to protobuffs and use those types in other languages. 100% recommended, Give it a try!!
doing a tictactoe doesn´t expose you to the problems it can have, dont get hooked up too quickly to stuff
@@vivarantx Did he mention he did a tictactoe?
graphql is great for public apis, trpc no so much.
trpc is great for internal apis, so is graphQL ( but requires more work ).
Yep! I’d say rest is slightly easier for public APIs, designing a GOOD public GraphQL api can be painful but it’s great if you pull it off 🙏🙏
Isn't there GRPC for TS?
yes, but TS people clearly like to lock themselves in the worst way possible so that they can use even more JS/TS. If any of these companies one day can't use TS/JS on the backend for whatever reason anymore, they are basically screwed and can do a full rewrite front to back.
My users and managers care very little about backend, plus it is recurring cost and exponentially growing complexity. Stateful backends so easily become cupboards of horror! I'm going to watch, optimistic tRPC can be used ti mitigate some of those negatives.
It would be cool to write a plugin for Next/Nuxt/Sveltekit so you could include your backend actions in components. So you could specify backend methods the same way you currently specify frontend methods. Even cooler if it could work with FaaS and hot-deploy both ends whenever you save your component source.
Kinda sounds like Remix
How do you handle versioning with tRPC? We usually deploy the back-end and front-end at different times and prefer to have a small window of backwards compatibility between the two.
Treat it as an accreting API for the duration of any deployment -- give the new implementation a different name, preserving the original implementation at the original name. Once you confirm all clients are using the latest version, push a breaking change that makes the old name have the new logic, and have clients use the old name. Once you confirm all clients are using the latest version, remove the new name. Basically the same way you do a breaking db schema change without deploying a distributed monolith.
Watch Rich Hickey's talk on how semver is broken for more on the concept of accreting APIs
with all the problems and anti-patterns that typescript has, using another language for backend is not a dumb idea. With highly distributed enterprise scale service ecosystems trpc won't work that well in my opinion. I personally don't enjoy coding in typescript. Golang is much more pleasant I think.
Also a question, in cases where graphql is not necessary, can protobufs be used instead of trpc?
That is super interesting point regarding being able to update your mobile apps on the fly like that with react-native.
did you try Odata and what do you think about it?
It kind of feels like we are going back to the past. As if we noticed how stupid we were for wanting to change things, like CSR to SSR/SSG (although we now have hydration), or from Rest and GrapQL to RPC... I wonder if we will diverge from this again in the future. This might be like retro going back on style
Can you upload your video on Spotify or Deezer ?
I watch your live streams, and I enjoy re-watching the cuts you post. Your content is pure gold! Thanks for everything.
i still can't get it. how can it be "the future" or "graphql killer" if it requires hard coupling frontend and backend (and omg monorepository for both), which is oblivious anti-pattern for any serious projects. Ofc it can take own place for small project, where small team is building both sides of application, but it will never kill or replace graphql or rest, until it does not have any out-of-the-box solution for projects, where frontend and backend are independent microservices
and tbh deepkit rpc looks much more professional compared to trpc
I think you've hit the nail on the head. The two biggest concerns in software design is coupling and cohesion. There's many benefits to tRPC, but the one big downside is a tightly coupled front and back end. Just depends on the project whether that tradeoff is justified.
So its like gRPC with types?
Not really
So - if i have an app where i am bound to using python on the backend for (django), how would I get something similar to tRPC? I am currently just going to use GraphQL but is there any way to get a similar setup to T3 stack with a python backend? Is my only option for something that measures up to go typescript backend?
Python is not typesafe. You can’t infer types from a language that isn’t typesafe lol
@@t3dotgg Gotcha, was thinking of something like mypy for pseudo type safety but thinking about it I can see how that was a silly question, asked after a night of no sleep lol
idk but I'm using graphql and I cannot define optional parameters for a resolver's input. So in the end... Lots of useless data traveling through the network.
We used JRPC an my previous company. Our back, and was written Node, then got rewritten and Go. I really like the simplicity of calling a function on the server.
Any thoughts on JRPC?
This video came at a perfect time. I have been wondering about this topic for a few days now.
So, in a situation where a developer is writing an entire application (frontend and backend) and has complete agency over the database, it seems like tRPC makes the most sense, right?
Yep! There’s no way you can build faster and faster in full stack :)
Does TRPC even work well with Nextjs and Vercel (serverless)? I can't do a single router for all backend queries because then all my backend code will end up in a single serverless function which is horrible for performance, infact we are going through a big refactor just to avoid that
NextJS auto splits Serverless functions when the JS bundle breaks 100mb. No perf issues at all :)
Building API version independent is amaizing. How do you do it?
I heard you say, 'those few use cases where typescript is very slow for your backend'. Being a junior and self taught dev, how would one differentiate between such usecases? I generally think if I have too complex data queries/ relations or the need to call my backend too many times on most of the pages, graphql is my guy. What such thinking should I apply on when to use TS or golang for a project?
Nodejs in general, regardless of using typescript or just regular JS is not really great for CPU intensive tasks. If your product is mostly just fetching data from a server or doing most stuffs like Crud operations Nodejs is still your guy. Whether you are using graphql or regular Rest Apis
east-west (service-to-service) communication is generally where you might start optimizing for performance by picking a different language. your BFF (backend for frontend) sits between clients and other services, and is an example of north-south communication. You can generally get away with using node for your BFF in the name of using the same language on your front-end and its backend and the benefits that provides (e.g. shared validation logic using something like zod). Then you would offload CPU-heavy and/or ML workloads to some other service in an appropriate language (maybe Scala, maybe golang, maybe python-wrapped-performant-C++), ideally using grpc/protobufs/etc for communicating with those sorts of services.
tl;Dr if you're just doing basic CRUD on the backend, you're not likely to need to switch languages for performance reasons.
I wonder what the relation of tRPC to gRPC ist, if any?
Basically nothing in common
@@t3dotgg Okay, So they just happen to have similar names? Thx for the info!
Why do you think the GitHub GraphQL API is bad? Would love to understand the criticism and see you point out the problems you see based on the experience you have
Many Backends use legacy code that can't really be touched. Frontend on the other hand is always looking for latest and greatest. Graphql helps me merged both in a single endpoint for apps.
Hello Theo. I love thé idea behind t3. Especially because all the stacks there are those I feel quite comfortable with.
Given that NextJs is a Fullstack framework. If I want the next api be consumed by the mobile version developed in react native as well as the web. Is that pretty comfortable and easy?
If you can call it with postman/insomnia, it should work on mobile as well
i recently realized how graphql really just makes my life harder. it doubled my bugs, i have to fixed and refract code twice even with nexus. especillay when using it with prisma. i think i'm gonna trash graphql. i used to love it though for past few years but i finnally realized it's really not that usefull even with complex project.
I have been building a gqlgen backend with go and it’s been interesting thus far
I think, tRPC is goot fit for teams that mainly consists of full stack developers. graphql is more well suited for large teams that have separate devs for frontend and backend.
Dated ways? I love TS but calling other ways dated is silly. Java, C#, Python are still incredible tools for building modern backends.
It really hurts to listen to this because I'm missing out so much... At my company we're using untyped, untested and undocumented Javascript Microservices with mongodb.... Everything is a mess, we never really know what data we're gonna get... I would be so happy if I'd get any sort of typesafety at all... Even it weren't perfect..
Be the change you want to see. Just make sure you get compensated for doing additional work 👍🏼
I'll take a statically typed Backend with a well designed REST API over pretty much anything else.
I'm the Flutter developer that won't let go of their ways lmao. Subscribed so I can refresh my knowledge for the React side of dev. Love your channel! I have already learned so much
The thing that bothers me the most with tRPC is the fact that you are selecting the query by simple string and this means no autocompletion. You can't just hit ctrl + space and see all the available queries. It can be fixed by using string-like enums but I feel that it can be solved in a better way.
There’s auto completion with the simple strings! Also v10 is moving to nested objects lol
@@t3dotgg That's actually great! Thanks
This is nothing new. For example .NET's old WCF is based around this concept where you delcare an interface that serves as communcation contract. It's just creating an interface that will be implemented by your BE and then creating an object proxy on FE based on the interface. The interface's implementation becomes a controller and methods become actions with the proxy on FE serving as "smart fetch". The proxy can be generated or create at runtime using reflection. This can be generally achieved even in JS when using classes. However, this approach was eventually phased out as WCF got succeeded by ASP NET, but there are libraries that do this even for ASP NET.
The tRPC seems like a downgrade as u still need to perform the tRPC call explicitly by using client.query('name', input). I think the better way to do this would be doing it as .NET did using OOP by explicitly using object (of the given interface) to perform call which would automatically map to it's implementation on the BE. You may argue that interface does not exist at runtime and thus cannot be introspected to generate routes and proxies, but you may use abstract class instead. By this FE does not have to distinguish whether the object performs HTTP calls or is just "normal" object. You may argue that there has not been anything like this in TS/JS, but I think that is generally because it died out before Node.JS was created.
The benefit of joined versioning comes from the monorepor. No matter whever GraphQL, SOAP, REST etc... as long as it's a mono repo the versioning of FE and BE is joined.
Funny that when you write ASP NET with dot, youtube will auto delete your comment.
tRPC v10 is moving to the more object-y syntax you described here fwiw
@@t3dotgg One additional thing: The contract seems to be purely server-based in the current version of tRPC (declared by the BE). However there are certian situation where you might want to declare contract in FE code or even somewhere else. When using interfaces or classes they can generally be declared anywhere, even in different repos (and being shared using npm).
One last thing: If ancient .NET banking software showed me anything. This approach is a good servant but a bad master as it completely kills of reusability of the API by non-compatiable languages. For example when we were building React FE, we had to create additional BE in .NET as TS cannot consume .NET interfaces and we were not brave enough to hardcode routes in the client (and other related issues like picking proper HTTP method, deciding whether put input in body or query strings etc...). In order to be a proper abstraction for communication this proprietary .NET framework did not expose anything that could be used to at least generate TS (like swagger doc, because swagger is REST specific which would limit this framework to only use REST).
I think this has potential as router-and-proxy generator which can be configured for different communication protocols and scenarios (including swagger doc generator) to save time when language matches, but it should not prevent direct usage of the underlying communication protocol if necessary. So it's rather extend than replace.
Solid, too the point, and enjoyable :D great stuff as always
I just read a article from logrocket to understand what the actual difference to gRPC is and this is what they wrote: "While tRPC is indeed also a remote procedure call framework, its goals and basis differ fundamentally from gRPC. The main goal of tRPC is to provide a simple, type-safe way to build APIs for TypeScript and JavaScript-based projects with a minimal footprint"
This has to be the stupidest reason to basically build a completely new "protocol", that is not a protocol and nobody else can use.
So yeah, TS/JS people are one more time too stupid to use their own tooling and now need something like this because they can't properly deal with types, even though they already have the same data representation on the front and back-end.
tutorial on trpc
Theo, great insight on trpc vs graphql
What are some excellent GraphQL educational resources? Or do you expect for tRPC to really mature quickly?
Very interesting. GQL seems to be still very popular though… Hasura with TRPC would be possible? 😉
Is tRPC good enough for mobile apps? because one of the points graphql makes is the fetch just what you want philosophy to deal with slow, unreliable and expensive mobile data on phones.
what about unnecessary fields what will you get with query? GraphQL give me possibility to get only queried fields, also I can query two users by id with one query for example
RPC needs not for communication only, this need to connect two parts of one application in network
This is great solution for nextjs api part, but it's not GraphQL killer, because they cover different things
Thank you for this really good description of what tRPC is - I saw it around Twitter, but I didn't understand why it's useful.
The issue of over using GraphQL is dear to my heart - I work in a large bank, and they've recommended that all BFFs default to using GraphQL. Although everyone was enthusiastic about it because it's a chance to learn a new framework, it's resulted in over-complicated codebases for very simple BFFs, and new devs struggling to understand and extend those codebases.
I’m a Kotlin Android dev that you speak of, with React Native experience. I tend to agree with the attempt to share components between React Native and React web. My personal projects are all Typescript/React and I also use React Native, but I can’t deny the dev experience with Flutter is much better. But because Typescript allows me to hit multiple birds with one stone, I deal.
Brother you're on wring video IG
this shit goes so deep.
As a consumer I would way rather have a GraphQL endpoint. Having singular API endpoints limits you to whatever the developer had originally intended, while crafting a good GraphQL schema can enable a much broader set of use cases outside of what was originally thought of, and avoid things like over-fetching. Really click-baity title.
Did you…watch the video?
@@t3dotgg I did, and to your clickbait question of "Is GraphQL DEAD??" you gave a bunch of reasons and scenarios in which GraphQL is good. Also, it's really not that hard to interact with, both for devs and consumers, but ok. And you also talked about the stricter nature of tRPC; I've never heard of or used tRPC but based on your description that's how I understood it. If I misunderstood maybe correct me instead of being a dick? But title is clickbait af regardless, hate how youtube took away dislikes number so I know clickbait content like this to stay away from
THEO
GO
TO
BED
Also stuck in GQL hell at work right now
Great video
Much love brother
Hard agree with the point about it being easy to use GraphQL to make hell. We use GraphQL a little bit at my company but we see no perceivable benefit from it and it just makes everything much more difficult.
Im still not a tRPC user yet. But can we take type safe advantage from tRPC while our app is not monolithic? Like in real world there would be microservices, multiple frontend repo, even microfrontend, blablabla and so on.
In this situation, is tRPC still a good choice?
U can have a monorepo for all ur microservices.
@@oscarljimenez5717 May be it won’t be suit to my company.
We separate all this for the ease of out sourcing , part time etc. it is supposed that the non full time staff won’t get the full source code.
Seems Pretty hard for us to adopt it in this situation.
May be next small project that we might try
Theoretically, all the tRPC client needs is the server's tRPC router type (which is the 'schema' the client will operate on, similar to how openapi clients can be generated from openapi specs).
So if you find a way to publish the type as its own package, you should be able to import it with tRPC in a client app.
Is it feasible? I don't know. But the cool thing is that no matter how many servers you would want to integrated with a single tRPC client, the amount of code running on the client is still the same. That's neat.
@@cuddlecake00 seems cool
Both tRPS and GraphQL are still very inefficient because of HTTP and JSON. If we swapped HTTP with QUIC and JSON with some custom low-level and binary parser then that would be absolutely amazing.
so you mean like gRPC
@@ThePapanoob Yup gRPC with a layer of some additional stuff
A swift and kotlin client would be great for mobile dev.
Using tRPC in a language that isn't Typescript is literally just REST with extra steps
GraphQL is the right solution if your clients are multi-language, even the creator of tRPC recommends gql for such
This man is the cat's ass of quality content. Thank you Theo. Gg
TL;DR - If you're not using TypeScript in front and back-end, and don't have full code visibility, This Tool Is Not For You. Move along, Move along.
No.
tRPC looks cool, but it really needs a better name
"is GraphQL DEAD?? so..this requires type script on both the back end and the front end"
lol good jokes
You should rather compare tRPC with gRPC and then ask "Why tRPC?"
Your audio is -14.9 dB lower than it should be. I always have to turn up my speakers when listening to your videos and then have them blow my out of my chair when I start a new video by someone else :D.
I was critical on some stuff but great video and like I expected man when u get down to business - intelligent, great explanation. It’s like awww okay ya this is good stuff. Maybe I just caught some stream rants lol. Thanks 4tv !
Thanks for the show
I have used GraphQL with Contentful CMS, GraphCMS & FaunaDB. I don't know how tRPC will Integrate with these popular tools. Also Note that GraphQL Server Frameworks like GraphQL Yoga & GraphQL Helix & tools like Envelop, Envelop Plugins & GraphQL Tools with GraphQL Mesh & GraphQL CodeGen & more... are making GraphQL DX Awesome. Please make more explorations to current situation before going online.
If you use Postgraphile, you dont need to write resolvers.
now i understand the diff betwen u and prime... ,you are talk more in real situation or doing real staf about dev web
t3 uses Prisma... It's quite easy to go to GQL from there. Why bother with your tRPC?!
You should watch, like, any of my other videos if you want my thoughts in GraphQL as an automatically generated api 😂😂
Great well explained !
Graphql dead because you can get typescript coupling between frontend and backend?
Yolo
I dont know anything except graphql
Been using it since day one of employment 🥴
Hey please don't swear
hahaha love the flutter h8
Younger theo is so adorably insecure - I just want to ruffle his hair and tell him he's doing great :)
Why you guys cussin educational videos? Its so unsafe to watch even educational next to our kids? This just push me to unsubscribe
I hope your kids can't read replies because this is fucking dumb
I am using python as my backend very often and dont see why this should be dated or smth. If u r more comfortable with one or the other go and use it
Based
Cool
GraphQL -> perfect for a team of FE React devs and BE Rails devs.
tRPC -> perfect for fullstack Typescript devs.
Your content is great but I need to speed up the video to 1.5 cause you speak so slow 😂 😂
tRPC will have a short lifetime. In real large companies, no one will commit themselves to a single technology. This has to do with the availability of developers, and above all that this technology is not the optimal solution in all areas. The RPC stack isn't new, and there's a reason it hasn't caught on.