URL Shortener project: Feedback on best practices

I have reached the URL Shortener project and I love the journey so far. I was hoping I could implement some ‘Best practices’ in this project and not just have a working code and therefore would like your feedback on how I have done so far and how do I go about this in the future.

I understand this looks kinda big - but it essentially boils down to 2 questions.

Here is my entire code so-far, note: it’s partially complete --> https://glitch.com/edit/#!/rune-slope

What I need feedback/help on:

  1. When using mongoose, I understand you create a Schema and a Model (and that you can create DB entries by creating instances of this Model class and using save() function ). Do I ever have to export the Schema object? Am I correct in my assumption that you can simply export the Model object and create entities with it (and never bother with exporting it at all!).
    Why I am asking this: Model and Schema are disparate constructs, right now, I am creating both of them in the same .js file. I feel like I am doing something wrong with abstraction here.

Code:

const conn = require('./conn');       //Conn is the Mongoose object exported
//like so --> module.exports = mongoose;

const URLCollection = conn.Schema({                    // Do I need to bother exporting this?
  URL: {type : String, required: true, index: true},
  shortURL: {type : String, required: true}
});

const URLShortenerModel = conn.model('URLCollection', URLCollection); // I can simply create objects with this right? 

module.exports = URLShortenerModel;
  1. I don’t really understand how JS classloading works, but when I export the variable, it is fine if it is a URLShortenerModel is a const right? I mean, the JS file is going to loaded into memory for every request (Or am I completely wrong here). Any good reason why it should not be a const and should be a let or var instead?

Thank you for your help. Kinda new to JS :frowning: Any additional feedback welcome and appreciated!

Do I ever have to export the Schema object? Am I correct in my assumption that you can simply export the Model object and create entities with it (and never bother with exporting it at all!).

You only need to export something if something else in a different file needs to import it. In this case, your model is the only thing that needs it and it is in the same file so it doesn’t need to be exported. It is perfectly normal to have variables and functions in a file that are for internal use only. In general you want a “need to know” policy. Anything that is not needed outside the file shouldn’t be exported. The model will use it and will have access to the schema even if the model is used elsewhere. If you put an export in front of your schema, it wouldn’t break anything, but would be entirely unnecessary. I’m not smart enough to know if it would cause a minuscule hit in speed or size (I doubt it) but it just plain isn’t needed.

it is fine if it is a URLShortenerModel is a const right?
I’m assuming that that is a complex object that is being stored in URLShortenerModel. This is a slightly confusing subject in JS, but const does not mean it can’t be changed but just that it can’t be reassigned. And it doesn’t matter because you can change properties on that object. For example:

const obj = { greeting: 'howdy' };

obj = { greeting: 'bueos dias' }; // generates error

obj.greeting = 'howdy'; // perfectly legal and common

In any case, because it is an object (and not a primitive) you are really storing and exporting a memory address to that object. const just means that you cannot change the address, but you can still change the values in that block of memory that the address points to.

Again, a very confusing topic when you’re learning. It’s an important topic, but don’t get frustrated if it takes a while for it to sink in.

I mean, the JS file is going to loaded into memory for every request (Or am I completely wrong here)

No, it will be loaded on each instance of the server. Your server will be constantly running.

Any good reason why it should not be a const and should be a let or var instead?

In general, things should be const unless you need to reassign them. For primitive types, this may be necessary often. For data structures (e.g, objects, arrays, functions) this is often not the case. There is nothing wrong with using `let* with an object if you truly need to reassign it to a different object (as opposed to changing data inside the object) but this is often not the case.

These are great questions. But they are also difficult questions on confusing subjects. But it’s great that you want a deeper understanding. Just don’t get frustrated if it take a while for all this to sink in. I’m sure there is some great youtube video or internet article on how primitives are stored differently than objects. Keep up the good work.

1 Like

Thank you very much for your help @kevinSmith. That is all I needed to know. Your answer helped me a lot!