Como desacoplar arquivo num projeto Node Express?

Recentemente estou fazendo um curso na udemy sobre Node Express e de acordo com o código abaixo você pode perceber que o CRUD se encontra tudo num em um só arquivo, como se trata de um projeto simples não existe nada de mais colocar todas as rotas em uma arquivo.

Eu fiz uma pergunta para o professor e não entendi a resposta e gostaria de saber se você teriam condições de me ajuda a entender o que ele escreveu.

Eu perguntei isso;

Eu percebi que todas as regras de negócios da aplicação ficaram sobre a responsabilidade do arquivo server.js gostaria de saber se isso é um procedimento comum em grandes projetos ou se não for qual é a abordagem utilizada.

E o professor respondeu isso;

Olá, tudo bem?

Peço desculpa pela demora no retorno.

Na verdade o ideal é juntar a arquitetura de API que desenvolvemos no último módulo só que com a organização que vimos anteriormente, usando o padrão MVC, para separação de responsabilidade e para que seja a aplicar ser escalável em questão de manutenção de código.

Para qualquer dúvida, estou a disposição :wink:

Att,

var express = require('express'),
    bodyParser = require('body-parser'),
    multiparty = require('connect-multiparty'),
    mongodb = require('mongodb'),
    objectId = require('mongodb').ObjectID,
    fs = require('fs');

var app = express();

// body-parser
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
app.use(multiparty());

app.use(function(req, res, next){

    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    res.setHeader("Access-Control-Allow-Headers", "content-type");
    res.setHeader("Access-Control-Allow-Credentials", true);

    next();

});

var port = 8080;

app.listen(port);

var db = new mongodb.Db(
    'instagram',
    new mongodb.Server('localhost',27017,{}),
    {}
);

console.log('Servidor HTTP esta escutando na porta ' + port);

app.get('/', function(req, res){
    res.send({msg:'Olá'});
});

// POST(create)
app.post('/api', function(req, res){

    var date = new Date();
    var time_stamp = date.getTime();

    var url_imagem = time_stamp + '_' + req.files.arquivo.originalFilename;
    var path_origem = req.files.arquivo.path;
    var path_destino = './uploads/' + url_imagem;

    fs.rename(path_origem, path_destino, function(err){
        if(err){
            res.status(500).json({ error : err });
            return;
        }

        var dados = {
            url_imagem: url_imagem,
            titulo: req.body.titulo
        }

        db.open(function(err, mongoclient){
            mongoclient.collection('postagens', function(err, collection){
                collection.insert(dados, function(err, records){
                    if(err){
                        res.json({'status': 'erro'});
                    }else{
                        res.json({'status': 'inclusao realizada com sucesso'});
                    }
                    mongoclient.close();
                });
            });
        });

    });
});

// GET(ready)
app.get('/api', function(req, res){
    
    db.open(function(err, mongoclient){
        mongoclient.collection('postagens', function(err, collection){
            collection.find().toArray(function(err, results){
                if(err){
                    res.json(err);
                }else{
                    res.json(results);
                }
                mongoclient.close();
            });
        });
    });
});

// GET by ID(ready)
app.get('/api/:id', function(req, res){
    db.open(function(err, mongoclient){
        mongoclient.collection('postagens', function(err, collection){
            collection.find(objectId(req.params.id)).toArray(function(err, results){
                if(err){
                    res.json(err);
                }else{
                    res.status(200).json(results);
                }
                mongoclient.close();
            });
        });
    });
});

app.get('/imagens/:imagem', function(req, res){
    var img = req.params.imagem;

    fs.readFile('./uploads/' + img, function(err, content){
        if(err){
            res.status(400).json({ err });
            return;
        }

        res.writeHead(200, { 'content-type' : 'image/jpg' });
        res.end(content);

    });
});

// PUT by ID(update)
app.put('/api/:id', function(req, res){
    db.open(function(err, mongoclient){
        mongoclient.collection('postagens', function(err, collection){
            collection.update(
                { _id : objectId(req.params.id) },
                { $push : {
                    comentarios : {
                        id_comentario : new objectId(),
                        comentario : req.body.comentario
                        }
                    }
                },
                {},
                function(err, records){
                    if(err){
                        res.json(err);
                    }else{
                        res.json(records);
                    }
                    mongoclient.close();
                }
            );
        });
    });
});

// DELETE by ID(delete)
app.delete('/api/:id', function(req, res){
    db.open(function(err, mongoclient){
        mongoclient.collection('postagens', function(err, collection){
            collection.update(
                { },
                { $pull : {
                    comentarios : {
                        id_comentario : objectId(req.params.id)
                        }
                    }
                },
                { multi : true },
                function(err, records){
                    if(err){
                        res.json(err);
                    }else{
                        res.json(records);
                    }
                    mongoclient.close();
                }  
            );
        });
    });
});

Separa em módulos as regras de negócio:

http://nodebr.com/modulos-em-nodejs/

Não vejo sentido MVC em uma api desse tipo. Teria só a controller (que já é o seu post) e o model com acesso a dados e regras de negócio.

1 curtida