Best practice for hitting a POST Route Handler inside a server component?
Answered
Order posted this in #help-forum
OrderOP
Is using the fetch method considered best practice when hitting a POST route to my api from a server component? Seems to be what chatGPT recommends but since this is the first NextJS API I'm building I'm not quite sure. And yes, I know I can await the server component and directly get the data inside it, I just like to tidy things up and use api routes for my queries.
Answered by Netherland Dwarf
Trying to call an api route from a server component is an anti pattern
58 Replies
Netherland Dwarf
Its not
Netherland Dwarf
Trying to call an api route from a server component is an anti pattern
Answer
Netherland Dwarf
Because it does extra network requests
You want to instead create a reusable util that handles the fetching and returns the data to you
OrderOP
I've no idea how I'd do that
can you elaborate a little bit
Netherland Dwarf
You can just create a reusable function called fetchData that takes in a url and returns the response etc
OrderOP
so how would that be different from just doing fetch in the server component
Netherland Dwarf
You can do fetch in server thats fine too
But not fetching in server to a next.js api or route
Thats extra network
Which means slower performance
If you want to isolate code then use what i mentioned
The util function
OrderOP
so then what's the point of building route handlers at all
Netherland Dwarf
They are for client side
OrderOP
I see so I either a) directly get the data from my server component (without api routes just getting it from my db) and pass it to the client as props or b)make an api endpoint and fetch it from client
Netherland Dwarf
Yes
In next.js doc you will see that too
What i mentioned
OrderOP
Otherwise I'm just asking my server to do something FROM my server and then the request gets done
so I'm doubling the request in a sense
Netherland Dwarf
Yes double request
OrderOP
Okay, in general what would you recommend as a better approach? because so far (before building the api) I was just fetching the data inside a parent server component and passing it to the client component that's nested inside it
if I only have a single level client component is that okay? I'm guessing api endpoints are useful when there are multiple nested client components to avoid prop drilling?
also if I directly call my api endpoint on the client should I use something like react query?
Netherland Dwarf
React query has it use cases (to prevent race conditions etc)
In next.js doc it does say you fetch from server component lets say the parent and pass it to the child component
Thats okay
OrderOP
yeah that seems like the most intuitive and easiest
Netherland Dwarf
If multiple childs needs the datat
Then i have to double check but not sure if use context would be better suited
OrderOP
My app is very simple, it's a chat app and I just need to fetch a few things like the friends/conversations and messages so I don't really have nested client components
so I'm really making my life more complicated by building an api come to think of it
at the beginning I did everything using server actions but then I realized they have their own issues
like queuing and the fact that they're all post requests
so that's why I switched to API Routes last night
what I don't get about server actions is what happens if I do a promise.all inside a single server action, wouldn't that eliminate the queuing problem?
Netherland Dwarf
No.
If we are talking about race conditions
Also i double checked next.js doc https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns
They mention if you need to share data between component that have the same fetch request
They mention if you need to share data between component that have the same fetch request
Then still do the same fetch request in every component because next.js caches by default
OrderOP
yeah that's what I do
Netherland Dwarf
Thats for sharing between server components *^
OrderOP
I see
So I'm gonna leave server actions for the few singular post requests that I do have like sending a message (creating it in db) and adding a friend request
and then I'm gonna move all the db queries to their util functions and call those in respective server components and then pass them as props to client components
I think that's a good plan
Thanks a lot I really didn't think about that whole double request situation, and it's actually quite important for performance especially in a place like a chat app where people would often be traversing between pages
Netherland Dwarf
Im not sure about this, maybe someone else can confirm if this solution you say it the most optimal or not.
But react query maybe something you want to use for this app if concern about consistent state update
OrderOP
I'm going to try different things
issue with seeing what's "optimal" is that it's just a test app so I'm never going to reach a user base large enough to know if I've somehow messed up optimization-wise
even if I deploy it and give it to all my friends the load will never be enough to know if I've made a grave mistake
OrderOP
I thought about another potential issue tho..if I pass the data from the server component to the client component how would I send the errors back to the client?
- just don't call your api routes from your server component.
- if you need data to server component then call your db directly from the server component itself.
- use api routes to handle requests from clients or external source.
Also i recommend reading this blog : to add in extra security and management
https://nextjs.org/blog/security-nextjs-server-components-actions
- if you need data to server component then call your db directly from the server component itself.
- use api routes to handle requests from clients or external source.
Also i recommend reading this blog : to add in extra security and management
https://nextjs.org/blog/security-nextjs-server-components-actions
OrderOP
yeah seems like in the end i will need my api routes and I will need to fetch the data from the client because I forgot about a very important detail - if I fetch data in the parent server component the data gets refreshed only on page reload, so if there are new messages in a conversation and then you switch to another conversation and back to the initial one you don't get the new data because the only thing thats a client component is the conversation itself that gets the already fetched data.
I don't get it, but are you using web-sockets ?