DEV Community

Lolo
Lolo

Posted on

5 Production Mistakes That Changed How I Build Express APIs

I stopped thinking APIs break because of “complex code”.

They break because of boring things you didn’t take seriously.

Here are 5 lessons from production:


1. Validate early or suffer later

I used to validate inside the logic.

Then weird bugs started appearing far from the source.

Now I just kill bad requests immediately:

if (!req.body.email || typeof req.body.email !== "string") {
  return res.status(400).json({ error: "Valid email is required" });
}
Enter fullscreen mode Exit fullscreen mode

No validation inside business logic. Ever.


2. Your errors are part of your API contract

A generic 500 is useless in production.

Be explicit:

return res.status(401).json({ error: "Invalid API key" });
Enter fullscreen mode Exit fullscreen mode
return res.status(402).json({ error: "Insufficient credits" });
Enter fullscreen mode Exit fullscreen mode

If your error needs explanation in Slack, your API message failed.


3. Middleware order can break everything silently

I once debugged “broken auth” for hours.

It was just middleware order.

app.use(cors());           // must go first
app.use(express.json());
app.use(authMiddleware);
app.use("/api", routes);
Enter fullscreen mode Exit fullscreen mode

Move one line and everything changes.


4. Logging should be boring, not noisy

I’ve tried both extremes.

Both were wrong.

What actually helps in production:

console.log(`${req.method} ${req.path} -> ${res.statusCode}`);
Enter fullscreen mode Exit fullscreen mode

And for real debugging:

console.error({
  requestId,
  error: err.message,
  stack: err.stack
});
Enter fullscreen mode Exit fullscreen mode

Everything else becomes noise at 3AM.


5. Rate limiting is not “later”

I learned this after watching an endpoint get hammered and cost real money.

import rateLimit from "express-rate-limit";

const limiter = rateLimit({
  windowMs: 60 * 1000,
  max: 60,
  message: { error: "Too many requests" }
});

app.use(limiter);
Enter fullscreen mode Exit fullscreen mode

If your API has no limits, it doesn’t have protection. It has hope.


Final thought

Most API failures don’t come from complex engineering.

They come from ignoring the basics because “it’ll be fine”.

It won’t.

Production doesn’t care.

Top comments (0)