// LOADING
// LOADING
// LOADING_ARTICLE
Next.js is powerful because of how it fetches data — SSR, SSG, ISR, and Server Components all depend heavily on your API. If your API is messy, your frontend becomes slow, fragile, and hard to maintain.
Your goal should be: simple, consistent, and predictable APIs.
Here is how data should flow in a typical Next.js + Node.js app:
Next.js UI
↓
Data Fetching (fetch / axios)
↓
Node.js API (Express)
↓
Business Logic (Service)
↓
MongoDB
Keep your frontend thin and your backend responsible.
Choose REST when:
Example REST endpoint:
GET /api/users
GET /api/users/:id
POST /api/auth/login
Choose GraphQL when:
Recommended Express structure:
/api
│
├── /auth
│ └── POST /login
│
├── /users
│ ├── GET /
│ └── GET /:id
│
└── /posts
├── GET /
└── POST /
Example route:
jsrouter.get("/users", userController.getUsers);
Always return meaningful status codes:
200 — OK 201 — Created 400 — Bad Request 401 — Unauthorized 403 — Forbidden 404 — Not Found 500 — Server Error
Example:
jsres.status(200).json({ data: users });
Error flow:
Next.js → API → Error → Middleware → Response
Example Express error handler:
jsapp.use((err, req, res, next) => { res.status(500).json({ message: err.message }); });
Consistent errors make frontend handling easier.
Instead of returning everything at once, design your API like this:
GET /api/posts?page=1&limit=10&sort=desc
Example backend:
jsconst { page = 1, limit = 10 } = req.query; const posts = await Post.find() .skip((page - 1) * limit) .limit(Number(limit));
This keeps your app fast at scale.
Good caching improves performance.
Example headers:
jsres.set("Cache-Control", "public, max-age=60");
For Next.js, you can also use:
jsfetch("/api/posts", { next: { revalidate: 60 } });
Never break existing clients.
Use:
/api/v1/users
/api/v2/users
This helps when your app grows.
Server Component example:
jsasync function Page() { const res = await fetch("http://localhost:5000/api/v1/users"); const users = await res.json(); return <UsersList data={users} />; }
Keep fetching logic close to where data is used.
Returning too much data Inconsistent response formats No proper status codes No pagination Poor error handling
A great Next.js app starts with a great API. If your backend is clean, your frontend will naturally be faster, simpler, and more maintainable.