I'm building a URL shortener API using Express.js, and I'm encountering a route conflict issue. Here are the relevant parts of my setup:
router.get("/", getAllUrls);
router.get("/:id", getUrlById);
router.delete("/:id", deleteUrlById);
router.post("/", shortenUrl);
router.get("/:shortCode", redirectToOriginalUrl);
When I visit the route to redirect based on the shortCode (e.g., http://localhost:5001/oWBI), the getUrlById handler gets called instead, causing errors. The route /:id seems to conflict with /:shortCode.
Expected Behavior: /oWBI should trigger the redirectToOriginalUrl function. /12345 (example ID) should trigger the getUrlById function.
Current Error: The server attempts to process /:id for both cases, leading to errors when it cannot find an ID.
What I Tried: I tried rearranging the route definitions but couldn't achieve the desired behavior. Here's the error I receive when visiting http://localhost:5001/oWBI:
The issue is very simple, Let me break down what is happening here.
So, when you call http://localhost:5001/oWBI
, this matches with /:id
route syntax.
So, You need to make the /:id
route more specific so that it does not conflict with /:shortCode
. There are two common approaches:
/:id
Route.
This goes something like this:router.get("/", getAllUrls);
router.get("/get/:id", getUrlById); // a prefix before /:id to make it more specific
router.delete("/delete/:id", deleteUrlById); // same here too
router.post("/", shortenUrl);
router.get("/:shortCode", redirectToOriginalUrl);
/:id
Or, use a middleware to differentiate between valid IDs and short codes. For instance, if IDs are numeric and short codes are alphanumeric, you can handle this dynamically:router.get("/:param", (req, res, next) => {
const { param } = req.params;
if (isNumeric(param)) {
return getUrlById(req, res, next); // now we call our getUrlById which returns item by id
} else {
return redirectToOriginalUrl(req, res, next); // or we redirect to other url.
}
});
P.S: This is a very simple code i wrote in order to explain. If you want to go with this middleware approach you would have to research in depth and handle more edge cases.