Learning the Importance of Route Order in Express.js
While working with Express.js, I encountered a bug where a static route was returning 404 errors. The culprit? Route order. Here’s what I learned and how to fix it.
Prasad Nallajala
AuthorDeveloper Guy Who loves to explore every edge of life✨
Introduction
Express.js is one of the most popular frameworks for building Node.js applications. Recently, I faced a bug where an API route kept returning 404 Not Found, even though the controller logic was correct. The issue turned out to be something simple but crucial: route order.
The Problem
I had defined my routes like this:
// Dynamic route to get resource by ID
router.get("/:id", getResourceById);
// Static route to get resource details
router.get("/details", getResourceDetails);
When I tried hitting /details, Express didn’t use getResourceDetails. Instead, it treated "details" as the :id parameter. Since there was no record with that ID, it returned a 404.
Why Does This Happen?
Express matches routes in the order they are defined. The first route that matches the request path is executed. In this case, /:id matched before /details, so the wrong controller was being called.
The Fix
The solution was simple: define the specific route first, and the dynamic route after:
// Static route first
router.get("/details", getResourceDetails);
// Dynamic route after
router.get("/:id", getResourceById);
Now, Express correctly matches /details to the right controller.
Lesson Learned
- Always define static or specific routes before dynamic routes like
/:id. - Route order matters a lot in Express.js.
- A small misplacement can cause hard-to-trace bugs such as unexpected 404s.
Conclusion
This was a simple yet powerful reminder: Express routing is order-dependent. By being mindful of route definitions, we can prevent confusing errors and make our APIs more reliable.
I hope this saves someone else from the hours of debugging I went through!
Related articles
How a tiny if(user) check broke my Next.js login page
I spent hours debugging a blank Next.js login page, only to realize a tiny if(user) check was killing my UI. Here’s how I found the bug and why user && token matters. [conversation_history:38]