I'm building an app that serves videos to a front end client. My stack is Express/Angular/SQLite. The db doesn't hold users, only root. I'm concerned that my controllers are too hardcoded, but I'm wary of the balance between making controllers too dynamic such that I'm merely pigeonholing myself into an over-engineered framework.
Backend project structure:
/server
app.js //creates app-wide express instance and feeds necessary dependencies to child components
/config
db.auth.js //for sqlite
paths.js //references to location of videos and other assets
routes.js //defines the api the frontend requests
/controllers
/recipes
doSomethingRedundant.js //many controller methods require this
index.js //exports all recipes
index.js //exports all controllers
videoController.js //methods for Video model
peopleController.js //methods for Person model
playlistController.js //methods for Playlist model
//etc.
/database
sequelize.bootstrap.js //returns single app-wide instance of db connection
sqlite.db //database
/middleware
static.js //defining paths to static file locations
webhooks.js //other stuff, like build
/models
index.js //exports models for easy access to controllers
Video.js
Person.js
Studio.js
//etc
/services
index.js //main exporter
makeReel.js //makes preview strip via ffmpeg
/views
index.html //frontend is SPA, there is only one view, basically
I'm content with this structure. It's easy for me to understand and I know where everything is supposed to go. But, here's what my routes.js
file looks like:
var controllers = require("./../controllers/index.js");
module.exports = function(app) {
//this seems suspicious, but I can't explain lucidly why it feels wrong
app.get("/videos/:range/some", controllers.videos.getSome);
app.get("/videos/:id/one", controllers.videos.getOne);
app.get("/videos/:id/random", controllers.videos.getRandom);
app.get("/thumbs/:video/:thumb", controllers.images.getOne);
app.get("/thumbs/:video/range/:range", controllers.images.getMany);
};
And the video controller:
var async = require("async");
var path = require("path");
var _ = require("lodash");
var util = require("./../services/util.js");
var bootstrap = require("./../database/sequelize.bootstrap.js");
var sequelize = bootstrap.sequelize;
var models = bootstrap.models;
var recipes = bootstrap.recipes;
module.exports = {
getAll: function(req, res) {
models.Video.findAll()
.then(function(rows) {
res.send(getval(rows));
})
.catch(util.err);
},
getSome: function(req, res) {
var range = req.params.id.split(",");
models.Video.findAll({
where: {
id: {
$between: [range[0], range[1]]
}
}
}).then(function(rows) {
res.send(getval(rows));
}).catch(util.err)
},
//get the video ID and all associated model instances
getOne: function(req, res) {
recipes.getVideoInfo(req.params.id, function(result) {
res.send(result);
});
},
getRandom: function(req, res) {
models.Video.count().then(function(count) {
(function ran(except, range) {
var r = _.random(0, range);
if (r === except)
return ran(except);
recipes.getVideoInfo(r, function(result) {
res.send(result);
});
})(req.params.id, count);
}).catch(util.err);
}
};
function getval(arr) {
return arr.map(function(obj) {return obj.dataValues;});
}
I feel I'm committing a cardinal sin by splitting up a similar GET
request for video info into several similar getRandom
, getOne
, getSome
, getAll
methods. Is this a bad idea? Due to lack of experience I can't really tell.