CONTENTS
- Introductory
- What's MVC?
- What Happens When You Visit a Webpage
- Become the Computer: A Roadmap, Routes
- Become the Computer: A Roadmap, Controller Example
- Conclusion
This Blog Contains:
- Visualization of routing within Express
- Basic, basic review of MVC
- Does NOT contain explanation of Models or Controllers
INTRODUCTORY
So I’m learning how to code, and I’m holding on to the handlebars —get it?— for dear life. There’s so many “things,” with so much “stuff.” Along the way, my love of knowing what all the little files in my folders do is being blown out the window and swept away into the gutter to fall into the ocean to only be eaten by a shark. That shark is currently Express, Node, Handlebars, and somehow launching it at the moon hoping to catch the internet.
The biggest, baddest shark in the pond is Express. In particular, navigating between the files via routing. I'm starting to conquer the inner-understandings of it, and the best way that has helped me is to pretend I'm a computer. Beep boop!
This is very in the weeds when you're reading it, and is best explained in 10 seconds in-person, but this has been a very instrumental mindset in understanding how routes work within Express.
What's MVC?
MVC stands for Model, View, Controller. It's a way to organize our files within a project. We separate the files by what they do.
- Model, what stuff is.
- View, what stuff looks like.
- Controller, what the stuff does.
There is no program to install, no uniform name, no nothin'. It's simply just a way we name and place a file for our own personal zen.
What Happens When You Visit A Website?
When you open your browser and type in a website, your browser submits what is called a GET request. This is one of four basic request types for data. With that GET request, the server of the website is "listening" to where you go. Because you decided to organize your files by MVC, our router is now responsible to linking your files together so that the correct response is served to the client!
Become A Computer: A Roadmap, Routes
The single-most thing that has helped me patch all of (mostly) Express, is to think about if I was a computer on the server-side. This is the fun part!
For reference in this example of computer roleplay, our relevant file structure will look this:
.
├── controllers
│ ├── application.js
│ ├── birds.js
│ ├── index.js
│ └── lizards.js
├── index.js
├── models
│ ├── Bird.js
│ ├── Lizard.js
├── routes
│ ├── birds.js
│ ├── index.js
│ └── lizards.js
└── views
├── birdsflying.hbs
└── lizardscrawling.hbs
Your file structure of names, folders, conventions, might all be different. This is not a standard pattern, your routes can link anything to anything!
Our Journey Begins, Setting Up with index.js
As a highly advanced technological marvel, you need to be told a few things before you're ready to work. Who and what am I?
To do this, our index.js, with the main project folder, answers most of those questions.
Remember, we're the server!
const express = require("express");
// Cool, I'm going to be using Express today. I hope my user didn't forget to npm install express me!
const hbs = require("hbs");
// Looks like I'm also using Handlebars.
const app = express();
// Nice! When I see "app," I'm going to be calling the function named express.
const routes = require("./routes/index.js");
// Uh-huh... I see that when I call the variable "routes," I'm going to be shooting it over to the routes folder!
app.use(express.static("public"));
// Looks like I'll be serving "static" files today, such as CSS and JavaScript.
app.set("view engine", "hbs");
// Oh right, I'm supposed to use hbs when I go to display things.
app.use("/", routes);
// When I get something, I'll call the "routes" variable. Good thing I defined it above!
app.use(require("./routes/index.js"));
// I need the routes/index.js file, OR ELSE I QUIT. That'll show the user!
app.listen(3000, () => {
console.log("server is running");
});
// Oh cool, I'm listening on port 3000.
Now that we know who we are, we're all ears for the user input!
Ground Zero, index.js
We have a request! Someone visited Port 3000, now we're ready to role! This is a GET request, so all we need to do is show the user something. We know this, because we're born with it! (We know these things from Express and JavaScript built-in)
- Let's roll down our index.js file. At first, we just know who we are.
- Alright. The user is requesting the the page called pigeon
/birds/pigeon
. Whoah! One of my commands activates when I'm requested for/
!app.use("/", routes);
-
app.use("/", routes);
So based on this, I callroutes
. We defined it earlier, withconst routes = require("./routes/index.js");
. - Nice! That
require
means I go to that file now, and keep going!
Journey to the Routes Folder, routers/index.js
Specified as earlier with app.use("/", routes);
referencing const routes = require("./routes/index.js");
, our adventure to find out what happens when our user visits /pigeon has first taken us to the index.js file within routes.
The routers/index.js file is basically responsible for funneling all the other routes together.
*Why? Future-proof our route so that we can simply refer to router/index.js instead of linking the routes directly.
We, the computer, read top to bottom. Using //
, let's follow our path and see where our files want us to go.
// Ahh, the routes index.js file! Good times here. Let's take a look... I'm looking to see where I should go for /birds/pigeon.
const express = require('express');
// Looks like I'm still using Express.
const router = express.Router();
// Okay, I'm using Express's Router method for the following. I need this because it's a part of the framework.
router.use('/', require('./application.js'));
// If user requests homepage, shoot them to ./application.js. Remember, . is current directory, but this isn't what we're looking for!
router.use('/lizards', require('./lizards'));
// If user requests /lizards, we will send them to lizards.js. Nope!
router.use('/birds', require('./birds'));
// If user requests /birds, we wil send them to birds.js. This is what we want, let's go!
Stepping into routes/birds.js
Yes! We're here, in routes/birds.js! Alright, what's in here?
const express = require("express");
const router = express.Router();
// Hey, I remember these!
const birdController = require("../controllers/birds");
// Huh. Alright, we have a variable called birdController, and it requires us to go to the controllers/birds.js file. We don't need to mark it with `.js`, because Express framework tells us to. Remember, `..` goes up a directory and we're currently in routes!
router.get('/', birdController.show);
// Hey, this is our path, birds/, but we're looking for /birds/pigeon. We just see / and not /birds because we're in /birds. Think of it as changing directories. So... Nope, not our stop!
router.post('/pigeon', birdController.create);
// This is it! This is /birds/pigeon! But there's one thing... I have a GET request, not a POST request. So this is the correct path, but not the correct action. Let's keep looking...
router.get('/pigeon', birdController.show);
// YES! Here is our GET request for /birds/pigeons. Let's see... It wants us to execute the .show method on birdController. What's birdController? Oh, right, we defined it up above! We need to travel to ../controllers/birds.js
module.exports = router;
// How we travel! Without this, we'd be trapped here.
Become A Computer: A Roadmap, Controller Example
Arriving At the Magic, controllers/birds.js
We made it! Controllers are where the action is. Think of controllers are normal JavaScript. This is what the guts are, and that normal JavaScript drives it. Look how the models come in to play now, this is where it all happens, lead to you dynamically thanks to routes!
Notice the method from before when birdController called birdController.show
, .show
being the method.
const Bird = require('../models/Bird');
const User = require('../models/User');
module.exports = {
create: (req, res) => {
console.log("This is what we weren't looking for!");
},
show: (req, res) => {
console.log("This is what we were looking for!");
// The code here would be executed with birdController.show.
}
};
Conclusion
Thinking about how the computer reads the code tremendously helped me understand why the code is written the way it is. I really hope it helped you visualize it and understand it too!
Find it helpful? Do I have any errors? Have questions? Have feedback? Let me know!
Thanks for reading, and Happy Coding!
~bananabrann
Top comments (1)
This is a great walk through!