Why is writing API logic in react (and NextJS) so difficult
Unanswered
JackO posted this in #help-forum
JackOOP
This isn't necessarily one problem I'm having but more of a broader annoyance with react. I'm struggling a lot with my application, where I know how to write the APIs needed for my application but there is no uniformity across my logic, and it feels like there are 100 ways to do everything. For example, should I define my types in the component where I need them or in a dedicated @/types/*.ts file? Do I write the api call methods in that same types file, or go to a @/api/*/route.ts file and then import the type I made and then write the logic in? It just seems so convoluted, especially when you can always just write EVERYTHING inside the component if you wanted to. Or could I even just have the page.tsx file host the logic inside itself and then pass props to a client component which has all the real page data. I don't know when I should be using which, or if I should just pick one, or what. The amount of options and libraries I have to do this feels paralyzing for productivity when I spend 90% of my time deciding HOW to do something and 10% actually doing it.
54 Replies
Dutch
as long as it works, no matter how and why you doing this. architecture comes much later than writing just working apps
its not react default its javascript theres even 3 module types as first like cjs, mjs, js with require etc
if you want to be led by some thing you can check angular or any other library but the power of react is just being this much flexible without breaking tbh
For example that error page is the best page you can see while debugging, its literally saying what you need to do
@Dutch For example that error page is the best page you can see while debugging, its literally saying what you need to do
JackOOP
That's true, I really have only ever used react
It just is not the type of programming I'm used to, where the methods of doing something are limited
@Dutch as long as it works, no matter how and why you doing this. architecture comes much later than writing just working apps
JackOOP
I feel like I have to do both at the time time but I could be wrong
I'm trying to create the MVP for a startup pitch which is a page that allows users to create companies and sort of like post blogs to them
I'm like literally the only person working on this MVP though
I say 'page' but in reality it is like 80% of the work for the complete web app
Should I worry about architecture now or just keep working and do what I need to do however it can be done? How do most people who are working in collaborative, structured environments do something like this?
@JackO Should I worry about architecture now or just keep working and do what I need to do however it can be done? How do most people who are working in collaborative, structured environments do something like this?
Dutch
No your first goal should be having a full working app under different conditions like wrong form inputs, quick page switches (anything can break website) then as you build more projects like after 3-5 you ll feel more confident and will look for easier and more strict ways to build same apps like writing small functions instead large pages etc.
React is different than your background but its really easy to understand and master imo. Takes some time but not much like Java or sth.
To exceed your limits try to write your whole code at same page then as code grows your architecture will be shaped based on your needs. There's no strict architecture rules though. Meanwhile you can check blogs, tutorials, docs to see how a large react project looks but before make sure you got all basics of react via building small projects. You can ask me about other details when you stuck too.
Just dont use any kind of AI in this "learning and gaining confidence" period
@JackO This isn't necessarily one problem I'm having but more of a broader annoyance with react. I'm struggling a lot with my application, where I know how to write the APIs needed for my application but there is no uniformity across my logic, and it feels like there are 100 ways to do everything. For example, should I define my types in the component where I need them or in a dedicated @/types/\*.ts file? Do I write the api call methods in that same types file, or go to a @/api/\*/route.ts file and then import the type I made and then write the logic in? It just seems so convoluted, especially when you can always just write EVERYTHING inside the component if you wanted to. Or could I even just have the page.tsx file host the logic inside itself and then pass props to a client component which has all the real page data. I don't know when I should be using which, or if I should just pick one, or what. The amount of options and libraries I have to do this feels paralyzing for productivity when I spend 90% of my time deciding HOW to do something and 10% actually doing it.
This isn't necessarily one problem I'm having but more of a broader annoyance with react. I'm struggling a lot with my application, where I know how to write the APIs needed for my application but there is no uniformity across my logic, and it feels like there are 100 ways to do everything.valid
For example, should I define my types in the component where I need them or in a dedicated @/types/*.ts file?whichever suits you best. i am using the former. you can even not define types and just infer based on definition. such as
type MyButtonComponentProps = React.ComponentProps<typeof MyButton>. you dont have to make a type everytime you make a component.Do I write the api call methods in that same types file, or go to a @/api/*/route.ts file and then import the type I made and then write the logic in?whichever suits you best, i am using the former. however, i usually dont "declare type" just to type cast the routes. Usually types are made to make top-level library calls communicates easier between other top-level library calls. In the route level, its better to keep it with
NextResponse and NextRequest to make it more readable and predictable.It just seems so convoluted, especially when you can always just write EVERYTHING inside the component if you wanted to.later you will find out that you can't and organizing files based on architecture layers is a better approach.
Or could I even just have the page.tsx file host the logic inside itself and then pass props to a client component which has all the real page datayes you could do that too
I don't know when I should be using which, or if I should just pick one, or what. The amount of options and libraries I have to do this feels paralyzing for productivity when I spend 90% of my time deciding HOW to do something and 10% actually doing it.true. but one thing is for sure: if you dont start doing, you wont figure out what works best for you. that 90% of your time is important so that you can start figuring out what you like and have style that makes you make stuff faster or avoid if its making you slower.
I'm trying to create the MVP for a startup pitch which is a page that allows users to create companies and sort of like post blogs to themFor MVP, you can try just write code as you need them. you dont need to prematurely abstractize everything or think of making types and such. do you even need the types? if no then dont do it. its not important for your mvp.
Should I worry about architecture now or just keep working and do what I need to do however it can be done? How do most people who are working in collaborative, structured environments do something like this?no, architecture emerges on the pattern you keep doing repeatedly. you can use existing architecture but figuring your own desired architecture takes time and is not worth the effort if you need something done ASAP. do what brok1 said. using existing architecture means you conform to whatever mindset the architecture aims to pleases. if it doesn't suit you dont bother. just like brok1 said, as your code grows, pattern will emerges and that would be the time you make layers based on your needs.
JackOOP
Ok great, both of you have been super helpful so I really appreciate that
So moral of the story is to just continue as I am and even spend that 90% of time figuring out "how" because it's time that I will be more confident and quicker later on
I think I got hung up because I was mixing frontend and backend conventions, where in the backend there usually are also multiple ways to do something, although typically one 'best' way emerges more quickly
I guess with the frontend, it is really more free flowing and on a needs-to basis
if it helps, in nextjs, you can write frontend like backends, or rather employ the backend mindset to it. its not the best mindset to make high quality frontend but boy it works and it is fast
JackOOP
Also I don't really know if I should be using state management libraries or just useState hooks, and should I use NextResponse for everything or just await fetch like I have been?
have you tried server action?
it simplifies the model a lot
do you struggle with useState hooks? if no keep using it, if yes then find a state mgmt libraries.
NextResponse is the thing you return from Nextjs API handlers. API handlers are called with await fetch. sooo the second question doesn't make sense. maybe check out server actions?
NextResponse is the thing you return from Nextjs API handlers. API handlers are called with await fetch. sooo the second question doesn't make sense. maybe check out server actions?
@alfonsüs ardani do you struggle with useState hooks? if no keep using it, if yes then find a state mgmt libraries.
NextResponse is the thing you return from Nextjs API handlers. API handlers are called with await fetch. sooo the second question doesn't make sense. maybe check out server actions?
JackOOP
What do you mean by server actions?
I should definitely already know but I think I am missing knowledge on a lot of this
@JackO What do you mean by server actions?
the ability to make server endpoints by just defining a function and calling the function directly (so no fetch api)
at worst one extra file per 'interaction'
at best no file since you can inline server actions in server components
at best no file since you can inline server actions in server components
@JackO Should I be using it at all?
uhh why not?
but im nots ure how well it works with existing state mgmt. u can definetly use it in native react client components
im sure there are lots of discussion regarding using server action with existing state mgmt
@alfonsüs ardani uhh why not?
JackOOP
Well with react as you know the question is always why and not why not
Since lots of stuff works
But that's weird that I've never seen a "use server" directive before, I guess it's not common in a lot of code
I usually just see it in a server component or something
@JackO But that's weird that I've never seen a "use server" directive before, I guess it's not common in a lot of code
its only prevalent in newer react version, which is only used in nextjs iirc
and its up to the framework on how they implement "use server"
JackOOP
Ah ok
I'll try it out then
@JackO I usually just see it in a server component or something
if it has "use server" it probably is not a server component, its def something else
JackOOP
I meant that the server components are left alone and then clients all include the directive anyways
But yeah I didn't even know about server actions maybe I'll try that
What should I be using NextResponse for again? Like every request or only certain kinds?
u meant when to use api handler?
JackOOP
Idk I just use fetch for everything
im asking did you mean "API Handler"?
did you mean "When should I be using API Handler for again? Like every request or only certain kinds?"
I read the chat and most of it has been told.
I struggled with this too when i started using react. Eventually i figured a consistent folder structure and file naming.
Here is my goto without overthinking:
types/index.ts (common types)
types/books.types.ts
services/books.service.ts (includes functions that handle logic for backend: getBooks,deleteBook..)
components/ui ->ui library components (things like button, typography, input)
components/any other component with its own folder structure (components/books/*.tsx)
you can create another folder to abstract DB queries (i did it in a project for example getBooks.db.ts that handles caching too)
Also i dont recommend server actions since you are not familiar with the concept because they are not just a function call. They have their own limitations and also you have to know about useActionState hook and how to use them with forms.
After that useTransition and more so id avoid it
I struggled with this too when i started using react. Eventually i figured a consistent folder structure and file naming.
Here is my goto without overthinking:
types/index.ts (common types)
types/books.types.ts
services/books.service.ts (includes functions that handle logic for backend: getBooks,deleteBook..)
components/ui ->ui library components (things like button, typography, input)
components/any other component with its own folder structure (components/books/*.tsx)
you can create another folder to abstract DB queries (i did it in a project for example getBooks.db.ts that handles caching too)
Also i dont recommend server actions since you are not familiar with the concept because they are not just a function call. They have their own limitations and also you have to know about useActionState hook and how to use them with forms.
After that useTransition and more so id avoid it