Node.js + Express Routing & Controllers PDF

Summary

This document explains the Model-View-Controller (MVC) design pattern. It details how to structure web applications using Node.js and Express.js, focusing on improving code organization and scalability through the separation of routes, models, and controllers. The document also presents practical examples and modularization techniques for better project management.

Full Transcript

Part 2: NodeJS + Express Structuring for Scalability: Routes and Controllers What is MVC? MVC stands for Model-View-Controller. It's a design pattern for software projects, widely used for developing web applications. MVC segregates the application into three interconnected comp...

Part 2: NodeJS + Express Structuring for Scalability: Routes and Controllers What is MVC? MVC stands for Model-View-Controller. It's a design pattern for software projects, widely used for developing web applications. MVC segregates the application into three interconnected components. The MVC pattern is valued for promoting organized and modular code, making it easier to manage complexity by clearly separating the application's different aspects. This separation improves code organization, scalability and reusability, leading to a more efficient development process. Model: This is the central component of the pattern. It is the application's dynamic data structure, independent of the user interface. It directly manages the data, logic, and rules of the application. The Model is responsible for handling the data: it defines the data structure, queries the database, and performs all the necessary data processing. View: Any representation of information such as a chart, diagram, or table. Multiple views of the same information are possible. The View component is used for all the UI logic of the application. It observes the Model and gets updated when the Model changes, presenting the user with a consistent output. React components act as the View layer. They are responsible for rendering the UI and presenting the data to the user. React maintains a state within components, and this state can be thought of as part of the "Model" in the MVC since it's where data is stored on the client side. Controller: The Controller acts as an intermediary between the Model and the View. It receives user input from the View, updates the Model accordingly, and then updates the View to reflect the changes. In the MERN stack, the Controller is implemented using Express.js. Express routes handle incoming requests, call the appropriate methods on the Model, and render the updated View. 1. Modularizing Express Routes with Controllers for Scalable API Development As demonstrated in Part 1, creating a CRUD (Create, Read, Update, Delete) REST API using Express is a straightforward process. However, consolidating all the code within a single file can become cumbersome and potentially confusing as the application grows. To enhance code manageability and reusability, it's a common practice among Express developers to compartmentalize code into various files and directories. This modularization allows for isolating specific functionalities into controllers, which can be invoked by multiple routes, thereby significantly improving the organization, readability, and maintainability of the codebase. Here is an example we used in part 1: app.get("/users", (req, res) => { res.status(200).json({ users: users });}); The goal here will be to split the route and its implementation code. To do so, we can use the Express Package called Router that allows you to create a list of all your app routes and associate them to specific controller files that contain the implementation code. This helps in managing the route handling logic in a modular and maintainable way. Routing refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST…). Note: You do not need to install express.Router separately from the Express framework. When you install Express it includes express.Router. 1.1 Establishing Directory Structure - Begin by organizing your project's main directory. You'll need to set up two distinct folders: one named 'Routes' and another named 'Controllers'. - Inside the 'Routes' folder create a new file called userRoute.js: This file will handle all routing related to User operations, centralizing the user-related routes in one place for better organization and manageability. - Inside the Controllers folder create a new file called userController.js: This file will contain the executable code for the routes you've defined. It will handle the user related logic defined in userRoute.js. Note: For consistency and clarity, it's standard practice to match the controller file name with its associated route file name. 1.2 Initiating Your First Route and Controller a) Modular Routing: Streamlining Endpoint Management User Routes Definition: Organizing User-Related Endpoints Building on the foundation set in part 1, the following snippet demonstrates how to organize and manage routes in an Express application. The separation of routing logic into a dedicated file, userRoute.js, which works in conjunction with a controller file to handle various user-related operations, will foster a modular approach that streamlines the code structure, making it more maintainable and scalable. Routes/userRoute.js const express = require("express"); const userRoute = express.Router(); // Import the controller functions from the user controller file. // These functions define the logic that will be executed when a route is matched. const { getUsers, postUser, putUser, deleteUser, getOneUser, } = require("../Controllers/userController"); // Route definitions userRoute.get("/users", getUsers); userRoute.get("/users/:id", getOneUser); userRoute.post("/users", postUser); userRoute.put("/users/:id", putUser); userRoute.delete("/users/:id", deleteUser); module.exports = userRoute; - const express = require("express"): It is necessary to bring in the Express module into your file. It's required to access the Router function. - const userRoute = express.Router(): Creates a Router Instance. - const{getUsers,postUser,putUser,deleteUser,getOneUser,}= require("../Controllers/userController"): This destructuring assignment extracts specific functions from the userController module. Each function corresponds to a CRUD operation related to user data. b) Centralized Request Handling: Streamlining RESTful Operations with Controllers User Management Logic: Centralizing Control in userController.js The userController.js file encapsulates the logic necessary for user management within our RESTful API. It serves as a dedicated module where we define functions responsible for handling requests related to users. Controllers/userController.js const users = [ { name: "mary", id: 1, age: 50 }, { name: "lisa", id: 2, age: 20 }, { name: "josh", id: 3, age: 30 }, ]; const getUsers = (req, res) => { res.status(200).json({ users: users }); }; const getOneUser = (req, res) => { const id = req.params.id; const founUser = users.find((user) => user.id == id); if (founUser) { res.status(200).json({ user: founUser }); } else { res.status(400).json({ msg: "no user found" }); } }; const postUser = (req, res) => { console.log("add user"); }; const putUser = (req, res) => { console.log("put user"); }; const deleteUser = (req, res) => { console.log("delete user"); }; module.exports = { getUsers, postUser, putUser, deleteUser, getOneUser }; While the functionality remains consistent with prior examples, the code has now been modularized into discrete functions, each accepting request (req) and response (res) parameters. This structural refinement enhances clarity and separation of concerns within our codebase. 1.3 Server Composition: Integrating Express Routers and Controllers with Environmental Configurations for Optimal API Functionality Secure Configuration: Leveraging Environment Variables for Safe App Settings In Node, environment variables are a great way to securely and conveniently configure things that don't change often, like URLs, authentication keys, and passwords. DotEnv is a lightweight npm package that automatically loads environment variables from a.env file into the process.env object. Note: environment variables are, by convention, generally written in all caps. To use DotEnv, first install it using the command: npm i dotenv - After DotEnv installation, proceed to generate a.env file at the root of your project's directory. Within this file, define your environment variables using the convention VARIABLE_NAME=value. As an illustration, to designate a port for your application, you may enter PORT=9001. This notation sets up the variable PORT with the value 9001. Access the Environment Variables Accessing your variables is done using the pattern process.env.KEY. If you ever need to change the value of any of your environment variables, you just need to alter the.env file. App.js const express=require("express"); const app=express(); const userRoute=require("./Routes/userRoute") const dotenv=require("dotenv") dotenv.config(); const port=process.env.PORT app.listen(port, (error)=>{ if(error){console.log("Server Failed")} else{ console.log(`Server Started on port ${port}`)} }); app.use(express.json()); app.use("/api", userRoute); Note that in this example the app.use("/api", userRoute) have routes prefix in '/api' This implies that all the URL paths defined within the routes file will automatically incorporate '/api' as a part of their path. 1.4 Testing with POSTman As shown in the image below, the response of the request outputs the message as intended, which means it works. We have successfully made our first route and controller.

Use Quizgecko on...
Browser
Browser