In this article, we'll go over how to build an express framework server backend using NodeJS.
Let's quickly review our outline listed below.
- What is expressJs framework? And why should I care?
- Initiating Server
- Server file structure
- Route handlers
- Routers and controllers
- Insert an introduction
What is expressJs framework? Why should I care?
Let's take a quick look at the express framework before moving on.
The express framework is a backend framework that runs on the nodeJS web server runtime and was created to speed up the construction of complex full-stack development projects as well as API web applications and cross-platform mobile apps.
Like other web development frameworks, express is a layer that sits on top of NodeJS and assists in managing servers, routes, and controllers. It is mostly used in the MERN stack. Mongo, Express, React, and NodeJS all make up MERN.
In other words, the multiple MERN stack technologies interact to build full-stack (i.e., front-end and back-end) web applications that are highly effective, complicated, and powerful. This makes it possible to separate the MERN stack into two blocks: a front-end and
Initiating Server
Let’s create and empty folder and name it Express, inside our Express folder, we create a folder called back-end, and a file server.js
Run the code on terminal npm init -y
This will create a package.Json
file inside our root folder, edit as so:
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node Backend/server.js"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Now let’s get some dependencies installed on our root folder
npm i express dotenv mongoose bcryptjs
These packages provide us with the following:
- o Express is the web framework we are using, which is necessary for our Express server
- o Mongoosejs is a package that connects our application to our MongoDB(database)
- o Bcrypt handles encrypting passwords and hashes
- o dotenv is what we use to create environment variables
After this is complete, you should see a node_module folder (this is where all the packages and dependencies are installed and saved to). We are also going to install a dev dependency called nodemon, which will constantly watch and run our server in real time so as not to restart our server anytime we make changes.
npm i -D nodemon
Also notice all our added dependencies installed successfully below.
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node Backend/server.js"
"server": "nodemon Backend/server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"dotenv": "^16.0.2",
"express": "^4.18.1",
"mongoose": "^6.6.0"
},
"devDependencies": {
"nodemon": "^2.0.19"}}
Server File Structure
As we have created our folders as well as various dependencies, our code can’t work without a server. Let’s create a server.js folder in our root directory.
const express = require('express')
const dotenv = require('dotenv').config()
const PORT = process.env.PORT || 5000
const app = express()
app.get('/', (req, res) =>{
res.send('Hello')
})
app.listen(PORT, () => console.log(`Server Loading on ${PORT}`))
Notice in line 3, our port is set using the ‘||’ data type to account for any missing PORT, we are now using the listen() method to start up a server that runs at localhost:5000.
To confirm that our server is now up and running, run the following:
npm run server
As far as environment variables go, we can employ our dotenv package that we installed previously, on our root directory we create a file called .env and edit as so:
NODE_ENV = development
PORT = 8000
To access this .env file we use the command process.env.PORT on our server file. Now, we go to our server.js file which will handle our entire backend server and edit as:
const express = require('express')
const dotenv = require('dotenv').config()
const PORT = process.env.PORT || 5000
const app = express()
app.get('/', (req, res) =>{
res.send('Hello')
})
//Accessing routes
app.use('/api/users', require('./routes'))
app.listen(PORT, () => console.log(`Server Loading on ${PORT}`))
we can confirm that our server is running at port 5000
The code above starts a server and listens on port 5000 for connections. The function responds with “Server Loading on port 5000 ” for requests to the root URL (/) or route. For every other path, it will respond with a 404 Not Found.
Route handlers
A route is a section of Express code that associates an HTTP verb (GET, POST, PUT, DELETE, etc.), a URL path/pattern, and a function that is called to handle that pattern.
A web application waits for HTTP(Hypertext-transfer-protocol) requests from the browser (or client). When a request is carried out, the application works out what action is needed based on the URL pattern and data contained in POST data or GET data.
Then the web application returns a given response based on the request received from our server.js above, notice the app.get() method specifies a callback function that will be invoked whenever there is an HTTP GET request with a path ('/'), the first two lines import the express module and create an express application.
This app object is unique in that it has methods for routing HTTP requests, initiating the .env, rendering HTML web views etc. Now, let’s create a route for our server, by creating a file called Routes.js in the backend folder and edit as so:
const express = require('express')
const router = express.Router()
const {FirstRouter, SecondRouter} = require('./controller')
router.post('/', FirstRouter)
router.post('/', SecondRouter)
module.exports = router
In order to use our code, we have to use the module.export = router command and notice the app.use() function. This function connects our server to the router, taking two functions: the URL endpoint and the path of our route file.
Routers and controllers
Controllers are responsible for handling incoming requests and in turn give back a response containing data back to the user (client).
Controllers take in the callback function which is initialized to get requested data from the models. Let’s store our controller in a separate "controller" module:
const FirstRouter = (re, res) =>{
res.send('First user route')
}
const SecondRouter = (req, res) =>{
res.send('second user route')
}
module.exports = {
FirstRouter,
SecondRouter,
}
It’s best practice to have a controller function to make our code cleaner and easier to maintain
Conclusion
We've now created a basic express server, along with dummy controller functions that we can populate with a full implementation in later articles.
Along the way we've learned a lot of fundamental information about Express installations, routes, servers and some approaches for structuring our routes and controllers.