Proper way to structure your node express application

By: Ryan Wong at

While researching the correct way to implement your api, no one gives a
precise way to structure your routes. So heres my take on this.

Say you have a route “/apiCall” and it returns a users profile.

Some changes I would make to this call:
1.I would rename it to “/api/v1/apiCall”. This way it’s very clear to the user that this is an api call and your using version 1 of this api. Also this allows you to depreciate old api calls safely allowing users to use a new version of api and the old.
2.call the api name something that has to do with their profile like “/api/v1/user/profile”.

#API Response
When you return an api response, you should always make use of the http status codes to make it clear to the user what went wrong. Doing this can make your api more robust and less code can be used.

Some common status codes I would use:

  • 200 (Successful call)
  • 304 (Not Modified) If the api response has not changed send cache version
  • 400 (Bad Request) If there was some validation error
  • 401 (Unauthorized Access) If user does not have authorization to make this call
  • 402 (Payment Required) payment is needed to make this call
  • 403 (Forbidden) Not allowed to access at all
  • 404 (Not Found) api route does not exist
  • 405 (Method not allowed)
  • 406 (Not Acceptable)
  • 407 (Proxy Authorization Required)
  • 408 (Request Timeout)
  • 410 (Gone)
  • 411 (Length Required) Content Type length required
  • 500 (Internal Server Error) Unknown error

#Structuring each Status error
To make use of all these status codes, I made an error object for each and return the error object with the next() callback.

##Error object

1
2
3
4
5
6
7
8
9
10
11
12
13
function UnauthorizedAccessError (code, error) {
Error.call(this, error.message);
Error.captureStackTrace(this, this.constructor);
this.name = "UnauthorizedAccessError";
this.message = error.message;
this.code = code;
this.status = 401;
this.inner = error;
}

UnauthorizedAccessError.prototype = Object.create(Error.prototype);
UnauthorizedAccessError.prototype.constructor = UnauthorizedAccessError;
module.exports = UnauthorizedAccessError;

##General Error handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
exports.errorHandleCode = function (err, req, res, next) {
var errorType = typeof err,
code = 500,
msg = { message: "Internal Server Error" };
console.log(err.name);
switch (err.name) {
case "UnauthorizedError":
code = err.status;
msg = undefined;
break;
case "BadRequestError":
case "UnauthorizedAccessError":
case "NotFoundError":
case "ValidationError":
//more error types ...
code = err.status;
msg = err.inner;
break;
default:
break;
}
return res.status(code).json(msg);
};

//In app.js file put this at end of file
app.use(errors.errorHandleCode);

#Api Method call
Now we put the whole api call together.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
app.post('/api/v1/user/profile', function(req, res, next){
//validation error
if (validationError){
return next(new ValidationError('400', validation.validationHandler()));
}
//find user
//var user = userFound;
if (!user){
return next(new UnauthorizedAccessError('401',{
message: "Unauthorized Access"
}));
}
//something serious went wrong
if (somethingSerious went wrong){
return next(new Error('Something serious went wrong'));
}
});