0% found this document useful (0 votes)
53 views33 pages

API Route 404 Fix

Uploaded by

Ola Badawy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
53 views33 pages

API Route 404 Fix

Uploaded by

Ola Badawy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

API route 404 fix

From the screenshot, it looks like your request is reaching the server but the server doesn’t
recognize the route you’re calling ( /api/v1 ). In other words, there’s likely no handler defined
for that path in your code. Here are a few things to check:

1. Verify the exact route path in your server code

In your server code, look for something like:


js

[Link]('/api/v1', someRouter);

If you see that, then inside someRouter , make sure you have a route for "/" or
whatever sub-path you intend to call. For example:

js

[Link]('/', (req, res) => {


// handle POST to /api/v1
});

If your route is actually "/test" (i.e., [Link]('/test', ...) ), then your


POST request should go to [Link]
[Link]/api/v1/test (not just .../api/v1 ).

2. Check for typos or mismatched paths

Sometimes you’ll define [Link]('/api/v1/products', productRouter) in your


code, but you’re calling [Link] . That mismatch will lead to a 404
because the /api/v1 path by itself doesn’t exist.

1/33
3. Confirm the HTTP method

Make sure your server code is actually handling a POST on that route if you’re
sending a POST request. If your server only has a GET route, a POST request will
also result in a 404 (or method not allowed, depending on your setup).

4. Check deployment environment

If this is deployed on Railway, ensure your environment variables (if any) and your
start command are set correctly. Sometimes the local environment route works but
the deployed one doesn’t if the path is not exported or if there’s a different prefix.

5. Add a basic “catch-all” route or error log

Temporarily add something like:


js

[Link]('*', (req, res) => {


[Link](404).json({ success: false, message: 'Not found' });
});

This can help confirm that your app is running and that the request is truly hitting a
non-existent route.

Check your server logs on Railway to see if you get any errors about missing routes
or other deployment issues.

In short, you’ll want to make sure the path in your request matches exactly the path you’ve
defined in your code—both in terms of URL and HTTP method. Once you confirm they
match, the 404 should go away. If you’re still stuck, try sharing your route definitions
(anonymizing any sensitive info) so we can pinpoint the mismatch.

2/33
From the screenshot of your [Link] , the key detail is that you only have a GET route defined
at /api/v1 :

ts

[Link]('/api/v1', (req: Request, res: Response, next: NextFunction) => {


[Link]('api is working');
});

You’re not defining any POST handler at /api/v1 . That means if you try to POST to
/api/v1 , Express won’t find a matching route—hence the 404.

Where to define your POST route


If you want /api/v1 itself to accept POST requests, you’d need something like:

ts

[Link]('/api/v1', (req, res) => {


// handle POST to /api/v1
});

Otherwise, if you want to create resources like products, orders, etc., you already have:
ts

[Link]('/api/v1/products', productRouter);
[Link]('/api/v1/users', userRouter);
[Link]('/api/v1/orders', orderRouter);
[Link]('/api/v1/discounts', discountRouter);

In that case, you’d do something like POST /api/v1/products or POST /api/v1/users


depending on what your router is handling.

Double-check your route usage


If your productRouter has a route like [Link]('/', createProduct) , then the
actual endpoint is POST /api/v1/products .

If your userRouter has [Link]('/', createUser) , then the endpoint is POST


/api/v1/users .

And so on for orders and discounts .

3/33
Summary
404 means the path you’re hitting doesn’t match any defined route/method.

You only have a GET route at /api/v1 .

If you need a POST route at /api/v1 , define it explicitly. Otherwise, use the resource-
based endpoints (e.g. POST /api/v1/products ) you set up in your routers.

Based on your discountRoutes screenshot, it looks like the POST route is defined at:

arduino

[Link]('/', createDiscount);

Because you are using [Link]('/api/v1/discounts', discountRouter); in your main


[Link] , that means the full URL for creating a discount is:

bash

POST /api/v1/discounts

So if you’re trying to create a discount, make sure you send your request to that exact
endpoint. For example, in Postman (or wherever you’re testing):

1. Method: POST

2. URL: [Link]

3. Body: (JSON with whatever fields your createDiscount controller expects)

If you send a POST request to /api/v1 instead, you’ll get a 404 because there’s no POST
route defined at /api/v1 in your code.

4/33
what about get and put

From the screenshot, your discountRouter has these routes (based on typical REST patterns
and naming conventions):

1. GET all discounts

Endpoint: GET /api/v1/discounts

Description: Retrieves a list of all discounts.

2. GET a single discount

Endpoint: GET /api/v1/discounts/:id

Description: Retrieves the details of a specific discount by its id .

3. POST a new discount

Endpoint: POST /api/v1/discounts

Description: Creates a new discount.

4. PUT (update) a discount

Endpoint: PUT /api/v1/discounts/:id

Description: Updates all fields of an existing discount with id .

5. DELETE a discount

Endpoint: DELETE /api/v1/discounts/:id

Description: Deletes the discount with id .

Because your [Link] file has:

ts

[Link]('/api/v1/discounts', discountRouter);

That means all of these routes are prefixed with /api/v1/discounts . So for:

GET all: GET [Link]

GET one: GET [Link]


[Link]/api/v1/discounts/123 (for example, if the ID is 123 )

PUT: PUT [Link]

… and so on.

5/33
Just make sure you replace 123 with the actual discount ID you want to retrieve or update.

From the screenshot, notice that the error message says:

arduino

"Route /api/v1/Discounts not found"

but in your code, you’re using:

ts

[Link]('/api/v1/discounts', discountRouter);

That’s all lowercase discounts . In many environments (especially on certain servers or if


case sensitivity is turned on in Express), "/Discounts" won’t match "/discounts" .

How to fix
Make sure you’re calling exactly:
bash

GET [Link]

(all lowercase) rather than "/Discounts" with a capital D .

Double-check your routes


Inside your discountRouter , you have something like:

ts

6/33
[Link]('/', getDiscounts); // for GET /api/v1/discounts
[Link]('/:id', getDiscount); // for GET /api/v1/discounts/:id
// ...

So the correct endpoint to list or fetch all discounts is:

bash

GET /api/v1/discounts

If you accidentally type /api/v1/Discounts (capital D), you’ll get a 404.

2/2

import { Request, Response, NextFunction } from "express";


import Discount from "../models/discountModel";

// Create a new discount coupon


export const createDiscount = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const {
code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses,
} = [Link];

// Check if coupon already exists


const existing = await [Link]({ code });
if (existing) {
[Link](400).json({ message: "Discount code already
exists" });
return;
}

7/33
const discount = await [Link]({
code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses,
});

[Link](201).json(discount);
} catch (error) {
next(error);
}
};

// Retrieve a discount coupon by its code


export const getDiscount = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const { code } = [Link];
const discount = await [Link]({ code });
if (!discount) {
[Link](404).json({ message: "Discount code not
found" });
return;
}
[Link](discount);
} catch (error) {
next(error);
}
};

// Update a discount coupon by its code


export const updateDiscount = async (
req: Request,
res: Response,
next: NextFunction
) => {

8/33
try {
const { code } = [Link];
const updateData = [Link];
const discount = await [Link]({
code }, updateData, {
new: true,
});
if (!discount) {
[Link](404).json({ message: "Discount code not
found" });
return;
}
[Link](discount);
} catch (error) {
next(error);
}
};

// Delete a discount coupon by its code


export const deleteDiscount = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const { code } = [Link];
const discount = await [Link]({
code });
if (!discount) {
[Link](404).json({ message: "Discount code not
found" });
return;
}
[Link]({ message: "Discount code deleted successfully"
});
} catch (error) {
next(error);
}
};

// Apply a discount coupon


export const applyDiscount = async (

9/33
req: Request,
res: Response,
next: NextFunction
) => {
try {
const { code } = [Link];
const discount = await [Link]({ code });
if (!discount) {
[Link](404).json({ message: "Discount code not
found" });
return;
}

// Check if discount is active and within the valid date


range
const now = new Date();
if (
![Link] ||
[Link] > now ||
[Link] < now
){
[Link](400).json({ message: "Discount code is
expired or inactive" });
return;
}

// Check if the discount has remaining uses


if ([Link] >= [Link]) {
res
.status(400)
.json({ message: "Discount code has reached its usage
limit" });
return;
}

// Increment the use count


[Link] += 1;
await [Link]();

[Link]({ message: "Discount applied successfully",


discount });
} catch (error) {

10/33
next(error);
}
};

Below is a quick rundown of how each controller function works and the typical routes you’d
assign them to in your [Link] (or similar) file. This will help you confirm how to
call them from your client (e.g., Postman, front-end app) and how they interact with your
Discount model in MongoDB.

1. Create a new discount – createDiscount


Code summary

Expects these fields in the request body:


js

{
code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses
}

Checks if a discount with the same code already exists. If yes, returns 400 with
"Discount code already exists" .

Otherwise, creates a new Discount document in MongoDB and returns 201 with the
newly created discount.

Typical Route

ts

// [Link]
[Link]('/', createDiscount);

11/33
How to call (Postman example)

bash

POST /api/v1/discounts
Content-Type: application/json

{
"code": "SUMMER2025",
"description": "Summer sale 2025",
"discountPercentage": 10,
"startDate": "2025-06-01",
"endDate": "2025-07-01",
"maxUses": 100
}

2. Retrieve a discount by code – getDiscount


Code summary

Reads code from [Link] .

Finds a discount in MongoDB by code .

If not found, returns 404 with "Discount code not found" .

If found, returns the discount object.

Typical Route

ts

[Link]('/:code', getDiscount);

How to call (Postman example)

bash

GET /api/v1/discounts/SUMMER2025

12/33
3. Update a discount by code – updateDiscount
Code summary

Reads code from [Link] .

Takes all fields from [Link] ( updateData ) and updates the discount in MongoDB
using findOneAndUpdate .

If not found, returns 404 with "Discount code not found" .

Otherwise, returns the updated discount object.

Typical Route

ts

[Link]('/:code', updateDiscount);

How to call (Postman example)

bash

PUT /api/v1/discounts/SUMMER2025
Content-Type: application/json

{
"description": "Updated summer sale",
"discountPercentage": 15
}

4. Delete a discount by code – deleteDiscount


Code summary

Reads code from [Link] .

Deletes the discount in MongoDB by code .

If not found, returns 404 with "Discount code not found" .

Otherwise, returns a success message.

13/33
Typical Route

ts

[Link]('/:code', deleteDiscount);

How to call (Postman example)

bash

DELETE /api/v1/discounts/SUMMER2025

5. Apply a discount – applyDiscount


Code summary

Expects code in the request body (not params).

Finds the discount in MongoDB by code .

Checks if it’s active and if startDate <= now <= endDate .

Checks if currentUses < maxUses .

If valid, increments currentUses by 1 and returns a success message along with the
discount data.

Typical Route

ts

[Link]('/apply', applyDiscount);

How to call (Postman example)

bash

POST /api/v1/discounts/apply
Content-Type: application/json

14/33
"code": "SUMMER2025"
}

Putting It All Together


Here’s a sample [Link] (or similar) that wires up these controllers:

ts

import { Router } from 'express';


import {
createDiscount,
getDiscount,
updateDiscount,
deleteDiscount,
applyDiscount
} from '../controllers/discountController';

const router = Router();

// POST /api/v1/discounts
[Link]('/', createDiscount);

// GET /api/v1/discounts/:code
[Link]('/:code', getDiscount);

// PUT /api/v1/discounts/:code
[Link]('/:code', updateDiscount);

// DELETE /api/v1/discounts/:code
[Link]('/:code', deleteDiscount);

// POST /api/v1/discounts/apply
[Link]('/apply', applyDiscount);

export default router;

Then, in your main [Link] (or [Link] ):

15/33
ts

import discountRouter from './routes/discountRoutes';

// ...

[Link]('/api/v1/discounts', discountRouter);

With this setup, you can call the endpoints from Postman or your front-end exactly as shown
in the examples above (make sure you match the method, path, and body format).

Key Points to Remember:

1. Case Sensitivity: On most servers, "/discounts" is different from "/Discounts" . Make


sure your request path is all lowercase if your code uses lowercase.

2. Check the HTTP Method: For updating, use PUT ; for creating, use POST ; etc.

3. Check Request Body vs. URL Params:

getDiscount , updateDiscount , deleteDiscount use :code in the URL path.

applyDiscount expects code in the body.

That’s it! With this structure, you should be able to create, retrieve, update, delete, and
apply discount codes successfully.

can you write me the description for creating, retrieving ,


update, delete and apply discount codes just like that

Below is a concise, table-style description for each discount-related endpoint (Create,


Retrieve, Update, Delete, Apply) in a similar format to your screenshot. Adjust field names or
routes as needed for your actual implementation.

16/33
Create a Discount Code
Method Endpoint Description Request Body Response

POST /api/v1/discounts Creates a json5<br>{<br> "code": Returns the


new "SUMMER2025",<br> newly
discount "description": "Summer Sale", created
code. <br> "discountPercentage": discount
10,<br> "discountAmount": 0, object, e.g.
<br> "startDate": "2025-06- { "_id":
01",<br> "endDate": "2025-07- "...",
01",<br> "maxUses": 100<br>} "code":
"...", ...
}.

Retrieve a Discount Code


Request
Method Endpoint Description Body Response

GET /api/v1/discounts/:code Retrieves the None Returns the discount


details of a object if found, e.g. {
discount code "_id": "...", "code":
by its code "SUMMER2025", ... } . If
not found, returns a 404
error.

Update a Discount Code


Method Endpoint Description Request Body Response

PUT /api/v1/discounts/:code Updates an json5<br>{<br> Returns the


existing "description": "Updated updated
discount description",<br> discount
code by its "discountPercentage": object. If
code . 15,<br> the code is

17/33
Method Endpoint Description Request Body Response

"discountAmount": 5,<br> not found,


...<br>} returns a
404 error.

Delete a Discount Code


Request
Method Endpoint Description Body Response

DELETE /api/v1/discounts/:code Deletes an None Returns a success message


existing if deleted, e.g. {
discount code "message": "Discount
by its code . code deleted
successfully" } . If not
found, returns a 404
error.

Apply a Discount Code


Method Endpoint Description Request Body Response

POST /api/v1/discounts/apply Applies a json5<br> Returns a success


discount {<br> "code": message and updated
code to a "SUMMER2025" discount info, e.g. {
purchase or <br>} "message": "Discount
cart. applied
successfully",
"discount": {...} } .
If invalid, returns an
error.

Note:

18/33
1. Replace SUMMER2025 and other example values with the actual data you plan to use.

2. If your Express server is case-sensitive for routes, ensure you use the exact lowercase or
uppercase paths you defined.

3. Ensure you send the request body as valid JSON ( Content-Type: application/json ).

how to do that ?
reates a new Discount document in MongoDB and returns
201 with the newly created discount.

Here’s a quick rundown of how you can create a new Discount document in MongoDB using
Mongoose and return an HTTP 201 status code along with the newly created discount:

1. Define a POST route in your Express app (e.g., POST /api/v1/discounts ).

2. Extract the discount data from [Link] in your controller.

3. (Optional) Check for duplicates to ensure a discount with the same code doesn’t
already exist.

4. Create the discount using Mongoose’s create() method.

5. Send a 201 response with the newly created discount document if everything goes well.

6. Handle errors in a try/catch block and pass them to your error handler via
next(error) .

Below is a simplified example:

js

import Discount from "../models/discountModel";

export const createDiscount = async (req, res, next) => {


try {
const {
code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses,
} = [Link];

19/33
// Check if the discount code already exists
const existing = await [Link]({ code });
if (existing) {
return [Link](400).json({ message: "Discount code already exists" });
}

// Create the discount in MongoDB


const discount = await [Link]({
code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses,
});

// Return 201 (Created) with the new discount document


[Link](201).json(discount);
} catch (error) {
// Pass any errors to your error-handling middleware
next(error);
}
};

Key points:

Use [Link](201).json(...) specifically to indicate that a new resource was


successfully created.

Ensure your request body ( [Link] ) includes all necessary fields (e.g., code ,
discountPercentage , etc.).

Make sure your Mongoose model ( Discount ) matches the fields you’re sending.

import { Request, Response, NextFunction } from "express";


import Discount from "../models/discountModel";

// Create a new discount coupon


export const createDiscount = async (
req: Request,
res: Response,
next: NextFunction

20/33
) => {
try {
const {
code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses,
} = [Link];

// Check if coupon already exists


const existing = await [Link]({ code });
if (existing) {
[Link](400).json({ message: "Discount code already
exists" });
return;
}

const discount = await [Link]({


code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses,
});

[Link](201).json(discount);
} catch (error) {
next(error);
}
};

// Retrieve a discount coupon by its code


export const getDiscount = async (
req: Request,
res: Response,
next: NextFunction
) => {

21/33
try {
const { code } = [Link];
const discount = await [Link]({ code });
if (!discount) {
[Link](404).json({ message: "Discount code not
found" });
return;
}
[Link](discount);
} catch (error) {
next(error);
}
};

// Update a discount coupon by its code


export const updateDiscount = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const { code } = [Link];
const updateData = [Link];
const discount = await [Link]({
code }, updateData, {
new: true,
});
if (!discount) {
[Link](404).json({ message: "Discount code not
found" });
return;
}
[Link](discount);
} catch (error) {
next(error);
}
};

// Delete a discount coupon by its code


export const deleteDiscount = async (
req: Request,
res: Response,

22/33
next: NextFunction
) => {
try {
const { code } = [Link];
const discount = await [Link]({
code });
if (!discount) {
[Link](404).json({ message: "Discount code not
found" });
return;
}
[Link]({ message: "Discount code deleted successfully"
});
} catch (error) {
next(error);
}
};

// Apply a discount coupon


export const applyDiscount = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const { code } = [Link];
const discount = await [Link]({ code });
if (!discount) {
[Link](404).json({ message: "Discount code not
found" });
return;
}

// Check if discount is active and within the valid date


range
const now = new Date();
if (
![Link] ||
[Link] > now ||
[Link] < now
){
[Link](400).json({ message: "Discount code is

23/33
expired or inactive" });
return;
}

// Check if the discount has remaining uses


if ([Link] >= [Link]) {
res
.status(400)
.json({ message: "Discount code has reached its usage
limit" });
return;
}

// Increment the use count


[Link] += 1;
await [Link]();

[Link]({ message: "Discount applied successfully",


discount });
} catch (error) {
next(error);
}
};

Below is a step-by-step explanation of how the createDiscount function (from your code
snippet) creates a new Discount document in MongoDB and returns a 201 (Created) status
with the newly created discount.

1. Receive the Request


The function is triggered when an HTTP POST request hits the endpoint that’s mapped
to createDiscount .

Typically, this route is something like:


ts

// [Link]
import { createDiscount } from '../controllers/discountController';

24/33
[Link]('/', createDiscount);

So when the client sends a POST request to /api/v1/discounts (assuming your app
uses [Link]('/api/v1/discounts', discountRouter); ), this function runs.

2. Extract Data from [Link]

ts

const {
code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses,
} = [Link];

The function reads these fields from the request body ( [Link] ).

Make sure your client (e.g., Postman, frontend app) sends JSON data in the body, with
Content-Type: application/json .

3. Check for Existing Discount Code

ts

const existing = await [Link]({ code });


if (existing) {
[Link](400).json({ message: "Discount code already exists" });
return;
}

25/33
Before creating a new discount, it checks if a discount with the same code already exists
in the database.

If it does exist, it responds with a 400 (Bad Request) error and a short message.

The return ensures no further code in the function executes.

4. Create the Discount in MongoDB


ts

const discount = await [Link]({


code,
description,
discountPercentage,
discountAmount,
startDate,
endDate,
maxUses,
});

If the code is unique, the function calls [Link](...) to insert a new


document into your MongoDB collection.

The Discount model is imported from ../models/discountModel and is a Mongoose


model.

5. Send a 201 Response with the Newly Created Document

ts

[Link](201).json(discount);

If creation is successful, the function sends back:

26/33
Status Code: 201 (Created), which indicates a new resource was created on the
server.

JSON Body: the newly created discount document (including _id and any other
fields stored in MongoDB).

6. Error Handling

ts

} catch (error) {
next(error);
}

If any unforeseen errors occur (e.g., database connectivity issues), the function catches
them and passes them to your Express error handler via next(error) .

Putting It All Together


1. Route Definition: In your [Link] (or similar file):

ts

[Link]('/', createDiscount);

2. Client Request:

Method: POST

URL: /api/v1/discounts

Headers: Content-Type: application/json

Body (JSON):

json

27/33
{
"code": "SUMMER2025",
"description": "Summer Sale",
"discountPercentage": 10,
"discountAmount": 0,
"startDate": "2025-06-01T[Link].000Z",
"endDate": "2025-07-01T[Link].000Z",
"maxUses": 100
}

3. Server Action: The createDiscount controller runs, checks for duplicates, creates a new
record if none exists, and returns 201 with the newly created discount document.

That’s it! You now have a fully functional createDiscount endpoint that stores new discount
codes in MongoDB and returns them with a 201 status.

It looks like your code should accept a POST request to /api/v1/discounts , but Railway is
still responding with a 404 (“not found”). That typically means one of two things:

1. The deployed code on Railway isn’t the same as what you have locally.

Maybe you haven’t pushed your latest changes (the ones that add
[Link]('/api/v1/discounts', discountRouter) ) to the repository that Railway

deploys from.

Or there’s a build step issue where your [Link] changes aren’t actually
compiled/deployed.

2. A mismatch in your route definition (spelling, capitalization, or an environment-based


condition).

28/33
Double-check that your [Link] really has:

ts

import discountRouter from './routes/discountRoutes';


[Link]('/api/v1/discounts', discountRouter);

Make sure it’s '/api/v1/discounts' exactly (all lowercase) both in code and in
Postman.

If you’re using TypeScript, confirm that you’re importing and exporting everything
correctly, and that your build output is up to date.

Troubleshooting Steps
1. Confirm the route usage in [Link] :

Ensure you see [Link]('/api/v1/discounts', discountRouter); and not


'/api/v1/Discounts' or '/api/v1/discount' .

2. Check your server logs on Railway:

Go to your Railway project → Logs.

See if there’s an error message about failing to load the discountRouter , or if the
server is restarting/crashing.

You should see a line like Server running on port ... and no major errors at
startup.

3. Verify your deployed code matches your local code:

Push your latest changes to the branch that Railway is deploying.

Redeploy or trigger a new build on Railway.

If you’re using TypeScript, ensure your [Link] is correct and that the
compiled .js files include your updated routes.

4. Try a simple test route:

For example, in [Link] , add:

ts

29/33
[Link]('/test', (req, res) => {
[Link]({ message: 'Discounts test route works!' });
});

Then call GET [Link]


[Link]/api/v1/discounts/test .

If that also gives 404, it confirms the route never got registered in production.

5. Case Sensitivity:

Express can be case-sensitive if configured that way. If your code says


'/discounts' but you’re calling '/Discounts' , it won’t match. (But from your
screenshot, it looks all lowercase—just be absolutely sure.)

Likely Cause & Fix


Most often, this happens because your local code has the new route, but your Railway
deployment doesn’t. Make sure to:

Commit and push your latest code to GitHub (or wherever Railway pulls from).

Wait for or manually trigger the deployment.

Check the Railway build logs to confirm it built successfully.

After it finishes, test again with POST [Link]


[Link]/api/v1/discounts .

Once your deployed code matches your local code, the POST /api/v1/discounts route
should work as intended.

what can i do to solve that ?


the route never got registered in production.

If the route “never got registered in production,” it typically means your deployed code on
Railway doesn’t actually contain the changes that add [Link]('/api/v1/discounts',
discountRouter) . Here’s how you can fix that:

30/33
1. Confirm Your Code Is Pushed to the Correct Branch
Make sure you’ve committed and pushed all local changes to the branch that Railway is
deploying from (often main or master ).

If you’re using GitHub, check the repo on GitHub to ensure the latest commit has the
discountRouter code and the [Link]('/api/v1/discounts', discountRouter); line
in [Link] (or wherever you define routes).

2. Trigger a Fresh Deployment on Railway


Go to your Railway project dashboard.

If you see a button like “Deploy” or “Trigger Redeploy,” click it.

Alternatively, push another commit (e.g., update your README) to trigger a new build.

Watch the build logs to confirm it pulls in the latest code.

3. Check the Build & Runtime Logs


In the Railway dashboard, open the “Logs” tab while it’s building.

Look for any error messages indicating that your discountRouter file can’t be
imported or that [Link] fails to compile.

After deployment, watch the “Logs” or “Runtime Logs” to see if your server starts without
errors. You should see something like Server running on port ... .

If there’s a crash, you’ll see an error. Fix that error, commit, and redeploy.

4. Verify the Route Is Loaded in Production


Once the new build is live, test it by calling:
bash

31/33
curl [Link]

(assuming you’ve created a simple [Link]('/test', ...) route in


[Link] for debugging).

If you get a 404, it still means your code with the route is not present or not registered. If
you get a JSON response (like {"message":"Discounts test route works!"} ), the route
is recognized.

5. Double-Check Any Case-Sensitivity or File Path Issues


If you named the file [Link] but imported it as import discountRouter
from './routes/DiscountRoutes'; (capital D ), on some systems it might work locally
(case-insensitive file system) but fail in production (case-sensitive).

Make sure the route path is exactly '/api/v1/discounts' (all lowercase) both in code
and in your Postman request. If you wrote '/api/v1/Discounts' anywhere, that could
cause a mismatch.

6. Confirm Your Start Command


In your [Link] , ensure your start script is something like:

json

"scripts": {
"start": "node dist/[Link]"
}

or if using TypeScript:

json

"scripts": {
"start": "tsc && node dist/[Link]"
}

32/33
Railway must run the compiled code (if using TypeScript). If you haven’t compiled it or if
your build output is missing the new routes, the old code will run.

Summary
1. Push your latest changes to GitHub (or whichever repo Railway is watching).

2. Trigger a new deploy on Railway.

3. Watch logs to confirm the new code is actually built and started.

4. Test the endpoint again in Postman with the correct URL ( POST /api/v1/discounts ).

Once your deployed code matches your local code, your discountRouter route should
register, and you won’t see 404 errors anymore.

from my code who can create the discount coupon ?

From the code snippet alone, there’s no authentication or role check to restrict who can
create a discount. In other words, anyone who can successfully send a POST request to
/api/v1/discounts with the required data can create a discount coupon.

If you want to limit discount creation to certain users (e.g., only admins), you need to:

1. Add authentication middleware (e.g., JWT-based or session-based) to identify the user.

2. Check the user’s role (e.g., isAdmin ) before allowing the createDiscount controller to
run.

3. Return an appropriate response ( 403 Forbidden or 401 Unauthorized ) if the user isn’t
allowed to create discounts.

Right now, your createDiscount function does not perform any such checks, so by default
it’s open to all.

33/33

You might also like