2

I'm building a Node.js website in TypeScript that exposes a RESTful API.

What are the best practices for separating the different methods to different classes/files?

I guess that for each resource I need to create a separate class. For example:

class Customers{
    router.get('/customers');
    router.post('/customers');
    router.put('/customers');
    router.delete('/customers');
}

class Orders{
    router.get('/orders');
    router.post('/orders');
    router.put('/orders');
    router.delete('/orders');
}

Is this true? And what if I have many resources that only contain one method each one?

For example:

    router.get('/orders');
    router.post('/customers');
    router.put('/products');
    router.delete('/employees');

Edit: I was answered that I can put all the routes in a single file and just separate the handlers into multiple files. So my question is: How to order/separate them LOGICALLY into different files (regarding the examples I wrote in my question)?

Notice: I don't need a technical programmatic information but an abstract explanation for logic separation.

Alon
  • 10,381
  • 23
  • 88
  • 152
  • You no need to use class at all. You can use simple object. – Sathish Jan 31 '16 at 05:19
  • Check this answer : http://stackoverflow.com/a/33096610/4138339 it is a little similar. – Krzysztof Sztompka Jan 31 '16 at 13:09
  • @Krzysztof Sztompka thank you. Your wrote in your answer "You can split your routes into multiple files (in big application there may be hundreds routes)", but my question is how to separate LOGICALLY these routes into multiple files. – Alon Jan 31 '16 at 18:21

1 Answers1

3

I usually don't separate routes itself, all the routing is configured in the main application module:

// server.js

var routes = require('routes');  // handlers and not the route definitions
// list of routes
router.get('/orders', routes.orderList);
router.get('/orders/:id', routes.orderGet);
router.post('/customers', routes.customerCreate);

And under the routes folder I have the handlers:

├── routes
│   ├── index.js
│   ├── orderGet.js
│   ├── orderList.js
│   ├── customerCreate.js
│   ├── ...

The index.js has a list of all routers (I think it can be improved to be generated dynamically) and each route handler looks like this:

// Require dependencies
var Q = require('q');
var models = require('../models');

/*
 * GET order list.
 */

exports.route = function(req, res, next){
    // Handle input parameters, generate the response
}

My approach is to have one file per route and use naming like 'methodGroupMeaning', for example 'orderGet', 'orderList', etc.

This way files are naturally grouped in the file system (sorted by name). Even for a large project with many routes, it will be easy to find the route file you need and at the same time route modules stay small and clean.

Borys Serebrov
  • 15,636
  • 2
  • 38
  • 54
  • Thank you very much for the answer. I voted up, but to have a complete answer I need to know: how to separate the handlers into different files (regarding the examples I wrote in my question)? You gave me a specific example but I'm looking for RULES. – Alon Jan 31 '16 at 18:05
  • @Alon Do you mean rules you use to decide how to distribute routes across files? My approach is to have one file per route + naming like 'orderGet', 'orderList' - this way files are naturally grouped on the file system. Even for a large project with many routes, it will be easy to find the route file you need. – Borys Serebrov Jan 31 '16 at 18:47
  • Yes this is what I meant. Is your approach considered a best practice? What if you have a project with hundreds of routes? Do you create hundreds of files? And if so, how do you separate them logically into different folders? – Alon Jan 31 '16 at 21:24
  • @Alon I can't guarantee this is actually a "best" practice, but I think it is good. Even with hundreds of routes it will be easy to find the file you need because of grouping by name. I would not make the folder structure deeper. From my experience complex folder hierarchies don't make things better and only cause the confusion. – Borys Serebrov Jan 31 '16 at 21:43