I’m not expert enough to answer this with any real authority, but these are the same issues I was dealing with around the time I made my URL shortener, too. In fact, after someone on Gitter told me mine was a mess, I started again from scratch and completely redid it!
There are two main parts to your post, so I’ll try and address them both.
Firstly, the easy one: Hiding your private info when you push a repo to GitHub.
When developing locally it is common to either set environment variables for your computer, or to use a Node package called dotenv, which basically emulates the same functionality. These methods allow you to access special variables using process.env.[VARIABLE_NAME]
(eg, process.env.MONGO_URL, might be one that you use). That variable is hardcoded into your system or dotenv file (which can be .gitignored) so that the code you push is sufficiently hidden.
dotenv
can’t be used on Heroku though, because it is .gitignored, but you can set environment variables on heroku either from the terminal: heroku config:set MONGO_URL=mongodb://username:password@blahblahblah
, or you can set them using the Heroku dashboard under your app settings. They call them config variables.
Your other question about project architecture is open to debate and interpretation. It doesn’t hurt to read around about that stuff.
My takeaways so far have been that for tiny ‘Hello Worldy’ projects, architecture doesn’t matter. Once you start having a couple of hundred lines of code though, it gets a bit more manageable if it is organised.
How you organise it is up to you, and as long as it is consistent and sensible then it’s ok.
A common configuration for me in my backend apps has been like this:
-
one file called server.js
which handles my express and mongo set up, including all the appropriate middleware and making the appropriate connections
-
routes.js
handles the stubs of all my http requests. I don’t put all the things each route handles in this file, literally just the URL endpoint and a named function squirrelled away in another module. eg router.get( '/', userQueries.getPolls );
-
controllers/userQueries.js
contains the functions that the routes file depends on to do DB operations. One of the functions in there might look like this:
Expand
getPolls: function( req, res ) {
var db = req.db;
var polls = db.collection( 'polls' );
polls.find().toArray( function( err, docs ) {
if (err) {
console.log( err );
} else {
res.render( 'pages/home', { docs: docs, user: req.user } );
}
});
},
-
views/pages/home.ejs
(and a bunch of other ejs files) are my view templates. I also have views/partials/header.ejs
and some others for page snippets that get repeated (nav bars, CSS/JS links etc)
And…I think that’s my basic structure at the moment.
This is not perfect, and may not be entirely best practice, but the reason it benefits me is that if I suspect a bug is being introduced because one of my routes is a bit wonky, I can look in a 50 line file dedicated to routes, not an 800 line file that handles routes, views, database connections, database queries and anything else!
If you want to see all of that together, you can see one of mine here: Voting App