m_callens m_callens - 2 months ago 10
Node.js Question

Express route not correctly behaving

In my

app.js
, among other routes, I have a route specified as...

app.route('/api/patients/:id/medication').get(MedicationController.all).post(MedicationController.add)


The controller for this route, and all others is pulled in from an external module. The
GET
method for this route, however, is acting very strange while the
POST
works perfectly fine.

When I do a
GET
request to the route above with a valid
uuid
in the URL for the
id
parameter (e.g.
/api/patients/bd4d6d44-3af3-4224-afef-d7e9a876025b/medication
), there are no errors, but I get the response...

{
status:200,
data: []
}


This doesn't make any sense to me because I had updated the
MedicationController.all
function to also include another field for testing, so even if there were no results for the query, the response should be...

{
status: 200,
data: [],
test: 'TEST FIELD'
}


Another thing, that doesn't make sense to me is that I can put in
/api/patients/bd4d6d44-3af3-4224-afef-d7e9a876025b/medafsdghads
, or some other garbage sub route after the
uuid
and still returns the same strange response.

In case it matters, here is the actual handler...

export function all(req, res) {
let id = req.params.id

r.table('Patients').get(id).getField('prescriptions').run().then((results) => {
console.log(results)
return res.json({ status: 200, data: results, testField: 'TEST FIELD' })
}).catch((error) => {
console.log(error)
return res.json({ status: 400, message: 'There was an error finding the medication of patient ' + id, data: error })
})
}


Here are also all of the routes I have currently implemented as well...

/*********************
* PATIENT API ROUTES *
*********************/
app.route('/api/patients').get(PatientController.all).post(PatientController.add)
app.route('/api/patients/:last/:first').get(PatientController.findName)
app.route('/api/patients/:id').get(PatientController.findId)

/************************
* MEDICATION API ROUTES *
************************/
app.route('/api/patients/:id/medication').get(MedicationController.all).post(MedicationController.add)
app.route('/api/patients/:id/medication/expiration').put(MedicationController.updateAllExpirations)
app.route('/api/patients/:patId/medication/expiration/:medId').put(MedicationController.updateExpiration)

/*************************
* INSTITUTION API ROUTES *
*************************/
app.route('/api/institutions').get(InstitutionController.all).post(InstitutionController.add)
app.route('/api/institutions/:id').get(InstitutionController.findId)
app.route('/api/institutions/:name').get(InstitutionController.findName)

Answer

You have an overlap of routes that match the same URL:

// This one:
app.route('/api/patients/:last/:first')

// And this one: 
app.route('/api/patients/:id/medication')

Express doesn't match the most logical route, it matches the first declared route that matches the request. In your case, /api/patients/bd4d6d44-3af3-4224-afef-d7e9a876025b/medication matches the first route.

You should declare more specific routes (with less parameters to match) first.