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: replace tRPC with server actions from NextJS13 #1456

Closed
Lucasvo1 opened this issue May 30, 2023 · 16 comments
Closed

feat: replace tRPC with server actions from NextJS13 #1456

Lucasvo1 opened this issue May 30, 2023 · 16 comments
Labels
🌟 enhancement New feature or request

Comments

@Lucasvo1
Copy link

Is your feature request related to a problem? Please describe.

With server actions there is a more lightweight, zero configuration and type-safe way to handle data fetching.

Describe the solution you'd like to see

Remove tRPC and put in some examples using server actions.

Describe alternate solutions

No alternative solutions.

Additional information

No response

@Lucasvo1 Lucasvo1 added the 🌟 enhancement New feature or request label May 30, 2023
@c-ehrlich
Copy link
Member

see #1364

@sscotth
Copy link

sscotth commented May 31, 2023

TBF, I don't think server actions are referenced in #1364 only appDir. Either way, server actions are in alpha, not even beta yet. So it will very likely have significant breaking changes, replaced with something else, or dropped altogether. See the bleed responsibly axiom until it becomes stable.

@Lucasvo1
Copy link
Author

Lucasvo1 commented Jun 1, 2023

TBF, I don't think server actions are referenced in #1364 only appDir. Either way, server actions are in alpha, not even beta yet. So it will very likely have significant breaking changes, replaced with something else, or dropped altogether. See the bleed responsibly axiom until it becomes stable.

Well, like you see with the appDir migration in T3 now, it's better to start working on it now so that it's ready once it hits stable.

@anaibol
Copy link

anaibol commented Aug 28, 2023

I think Trpc integration on Nextjs is not only about data fetching but also about data state management on the frontend, it's built on top of React Query.

@Kamahl19
Copy link

@c-ehrlich Server actions are now stable, do you plan doing this?

@c-ehrlich
Copy link
Member

@c-ehrlich Server actions are now stable, do you plan doing this?

No.

We do "support" server actions, in the sense that it's a Next.js app and you can use them. But we have no plans to get rid of tRPC.

The Next.js team recommends using a data access layer for anything but quick prototyping. tRPC is that data layer for us.

In fact I'd recommend it even for quick prototyping, because:

  • you get better dx
  • you get better type safety
  • you get react query integration in client components
  • it's no extra work for you because Create T3 App takes care of all of the initial setup

@Kamahl19
Copy link

Kamahl19 commented Nov 21, 2023

The recommendation you linked only talks about the separation of concerns and not mixing data access with UI components. It says nothing about bringing 3rd party tools such as tRPC or Query into the stack. Achieving the "Data Access Layer" is also possible using "native/idiomatic" techniques which Server Actions are now, in Nextjs v14. Doing more with less should always be a preferred way.

@tomer-dev
Copy link

tomer-dev commented Jan 7, 2024

Adding to what @Kamahl19 said, I understand the part in the article on "Data access layer" as a recommendation for new projects to move the data access part into a "single library" where you can check input and auth, and on top of all you use DTOs.

After watching the "React+Servers=Confusion" video, I wonder what's the role of tRPC if we have the DTOs defined and we import server actions. Especially when the server actions can be imported on the client side.

I really love the work you do. I allow myself to raise this Q again as we learn and adapt to these new changes.

@tomer-dev
Copy link

tomer-dev commented Jan 7, 2024

Reddit discussion on keeping tRPC despite server actions in

After some research, let me know if tRPC integration with React Query and Next.js may be a reason for keeping tRPC even though with server actions we can RPC. From tRPC docs:

Our Next.js integration is built on top of our React Query Integration with some Next.js-specific APIs, to handle both client and server-side rendering.

Currently, making that server action call from the client will trigger a fetch call, extended by Next.js.
Perhaps the benefits from server actions are still not more compelling than those offered by tRPC?

e.g. relying on React Query rather than Next.js App Router when it comes to caching and revalidation

@markomitranic
Copy link

markomitranic commented Feb 16, 2024

@tomer-dev It is perfectly normal to use both react query and server actions, I use that in my projects:

  const { error } = useQuery({
    queryKey: ["posts"],
    queryFn: () => myServerAction("post-id"),
  });

With that said, I'd like to re-ignite your question one again. I'd like to have a discussion around the actual value of still using trpc. Looking at what is stated in this thread, let's break it one by one:

☑️ You must have a Data Access Layer - yes, but you can have it with either trpc or server actions, it doesn't really change much.
☑️ trpc gives you better dx - Not significantly better. T3 folks did build in some very nice things, like formatting errors, but on the other hand, the procedure declaration is uglier and more confusing. You win some, lose some.
☑️ trpc gives you better type safety - I'm not entirely sure what that even means. Zod ensures type safety, and linter helps. Both of these work exactly the same with server components.
☑️ you get react query integration in client components - as shown above, works exactly the same with server components.
☑️ it's no extra work for you because Create T3 App takes care of all of the initial setup - sure, but the whole point of this PR is to resolve this point.

So, no real difference in any of those points. I do wonder how trpc vs server actions affect your vercel costs tho.

@issamwahbi
Copy link

Hey,

@markomitranic , you are using a server action to fetch data with react-query. Nextjs are not recommanding this in their officiel documentation even if it works. From what I test, it fetch data with a POST request ..weird from web standards point of view !! it seems the recommanded approach from NEXTJS to fetch data is to use a server component...but not sur if that can cover all the cases.

In addition, I don't think server actions can yet replace tRPC functionalities. Server actions from client are a kind of RPCs. So you need from a good design point of view to handle data validation, authentication, authorization, error management ... before executing the server action logic. The best way in my opinion to do that is using a kind of middleware pattern. Some libraries out their like next-safe-action are trying to solve it.

I will even argue that at the moment tRPC is a better design decision than server actions. it gives more flexibility. For exemple if you need to reuse your api routes in a react native application.

in my opinion what will be the "ideal" solution is to be able to create tRPC routes as we do today and have a way to generate dynamically a server actions from it. with type safety and dynamic piping of the route middleware...

@tomer-dev
Copy link

tomer-dev commented May 29, 2024 via email

@markomitranic
Copy link

markomitranic commented May 29, 2024

@issamwahbi I understand what you are saying. I just want to clarify 2 things.

Try to differentiate between the domain logic we have to write (which is literally the same for any transport method) and the transport method itself. Be it HTTP, trpc, ws, server actions, or even server components - you still have to do auth, sanitization and validation and api minimization. Yes the shape of doing it may vary but you still have to do it every single time.

Now, focusing on the differences between transport methods - it is perfectly fine to use POST, a good example of that is graphql. The main reason not to use POST is the (im)possibility of CDN level caching, which has plagued graphql for the past decade. And, it is literally the same for both trpc and actions, both are uncacheable in a similar way. That is the real reason why HTTP+GET is being always recommended - it thrives on caching. With that said, it is clear that this doesn't really make any difference between trpc and actions.

As for tanstack-query, that is a misconception - you can in fact use it with literally anything. You can use it with local async functions as well, for example. T3 Trpc uses it as well. So saying that they can't or shouldn't be used with server actions is kinda silly. But not so silly if you think about it - a large majority of the user base of NextJS is new to the basic backend concepts, and expect the NextJS team to set boundaries and best practices, which is percicely why they chose to say bad idea for fetching by server actions, instead of going into long winded explanations and endless github tickets, explaining "why your stuff is not being cached".

P.S. Kinda reminds me of why merge was decided to be the default git strategy over --rebase. Rebase is better on multiple fronts, including the conflict resolution, but merge is entirely idiot proof and that is what makes it a great sane default for everyone. :D

@tomer-dev oh wow not sure what you mean by that, has anything new happened?

@markomitranic
Copy link

The Next.js team recommends using a data access layer for anything but quick prototyping. tRPC is that data layer for us.

@c-ehrlich can you please expand on this, I'd love to learn more. I don't see how TRPC is "a data layer for us". The main thing that a data layer does is API minimization, which trpc has nothing to do with - we have to write our own DTOs before shipping data to the client.

Some other activities associated with having a data layer:

  • Authentication
  • Input Validation & Sanitization
  • Scope/Permission control
  • API minimization (dtos and view/response transformation)

And none of these really have anything to do with our implementation of TRPC - the user has to write them themselves (yes, including input validation, which we use zod for).

Actually the only one out of all the data layer components, that we even remotely touch is that we require a zod definition as an input transformer, which again, nothing to do with trpc as a protocol, could be done with actions as well. So, our T3 trpc implementation basically just sets some general directions in terms of organizing our code elegantly, it does absolutely nothing to actually act as a data access layer.

So... what am I missing? Is there more functionality to our trpc implementation, that I don't know about yet :o

@tomer-dev
Copy link

tomer-dev commented May 29, 2024 via email

@tomer-dev
Copy link

tomer-dev commented May 29, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🌟 enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants