Hey Readers!
Out of frontend, database, and backend development, backend has always been the most challenging part for me. This article delves into my early journey in backend development with Node.js, sharing both struggles and insights. You’ll learn about the common beginner pitfalls and practical ways to navigate through them, gaining clearer understanding of key backend concepts.
Backend Blues and Initial Challenges
The Initial Struggles
Backend development has been a crucial part of the web development journey. For someone who finds joy in the creativity of frontend designs and the structured logic of databases, backend seemed like an uncharted territory—confusing and, honestly, not as exciting.
Yet, I chose to explore Node.js, a runtime environment for JavaScript. Why? Because it bridges the gap between frontend and backend using the same language, JavaScript. This promise of unification drove me to dive into the world of servers, APIs, and middleware.
Starting with Node.js was like entering a maze without a map. I had no clue how to run a program, what cors
, express
, or body-parser
meant, or why they were even necessary. My initial approach to setting up a backend was heavily reliant on seniors. But one day, they refused to help, encouraging me to learn through research and experimentation. It was a tough-love moment, but it was also the turning point in my journey.
Understanding the Basics
That was when I began to slowly understand the "why" behind all the confusing pieces of backend development. With persistence, I learned about tools like Express, CORS, and body-parser. These tools form the foundation of backend development:
Express: It is a Node.js framework that simplifies server creation by providing powerful tools to define routes, manage middleware, and handle requests and responses effectively.
CORS(Cross-Origin Resource Sharing): It is a mechanism that allows resources to be requested from a different domain. It is crucial for enabling communication between the frontend and backend hosted on separate servers (e.g., a frontend application hosted on one server to a backend API hosted on another are allowed, overcoming the "same-origin" policy limitations).
Body-Parser: A middleware that parses incoming request bodies, converting them into usable data formats (e.g., JSON), which streamlines handling data sent from the frontend.
Each of these tools had its role in connecting the frontend to the database and facilitating seamless communication.
The Role of NPM
npm
(Node Package Manager) was a revelation. It simplified installing and managing dependencies. Initially, I made the rookie mistake of including node_modules
in my .rar
files when sharing projects. A senior pointed out that I could use npm install
to re-download dependencies and avoid bloating my project files. That day, I also learned about .gitignore
for excluding unnecessary files from GitHub repositories.
Breaking Down the API Calls
Setting Up Your First Backend
Starting with npm init -y
became my ritual. From there, I installed necessary packages like express
and cors
. Once the setup was ready, I ventured into API calls. This was a significant milestone as it involved connecting various components and making the application functional. I learned that app.listen
starts the server, and .env
variables help manage sensitive data like database credentials. Middleware, such as body-parser
and custom logic for authentication, became essential for preprocessing incoming requests before they reached the server logic.
Making API Calls: GET, POST, PUT, DELETE
Understanding HTTP methods was a game-changer:
GET: Used to fetch data from the server. The parameters are typically passed via the URL, allowing the backend to retrieve and send the requested data.
POST: Designed for submitting data to the server, often sent in the request body for tasks like form submissions.
PUT: Helps update existing data on the server, ensuring that the data remains current.
DELETE: Removes specified data from the server.
Might sound funny but it took me months to fully grasp the difference between GET and POST requests and to correctly structure API calls. I often used to pass parameters in the API URL for POST requests, which is actually the correct method for GET requests. In a POST request, parameters should only be passed in the request body. Debugging these calls was another learning curve, involving tools like Postman for detailed testing.
Debugging APIs
Debugging backend code felt more challenging than frontend debugging because, in the frontend, you can easily add a debugger or use inspect tools. However, I gradually discovered that tools like VS Code's debugging features made it possible. I learned to start debugging from the server.js
file, ensuring I could trace issues effectively.
Modularizing APIs
Just as I modularized React components to improve organization and reusability, I learned to apply the same principles to APIs by organizing them based on functionality. This process involved separating routes and controllers into distinct modules, which made the codebase much cleaner and more manageable. By categorizing APIs according to their specific functions, I was able to streamline the development process, making it easier to locate and modify code when needed.
Optimizing API Performance
By analyzing response times in the network tab, I optimized database queries to ensure they were as efficient as possible, reducing the time it took to retrieve and process data. Additionally, some API calls were redundant, which led to unnecessary delays. For instance, instead of separate calls for updating table data and specific attributes, I streamlined the process by refining the logic to handle all updates in one comprehensive call.
Advanced Learnings
Authentication and Security with JWT
Securing APIs became a priority. Using JWT (JSON Web Tokens), I implemented authentication systems that ensured only authorized users could access certain data. This was vital for preventing sensitive data exposure in browser developer tools. Later, I advanced by using JAuth to authenticate users in an application and using tokens to fetch API data. This method of securing data is essential because, without it, any API fetch or retrieval shows data in the inspect network tab, which is a significant vulnerability for a proper application.
File Handling with Multer and File-Saver
Using libraries like Multer, I handled file uploads, while File-Saver allowed dynamic file downloads. These tools made it easier to manage user data efficiently. Multer is middleware for handling multipart/form-data
, which is commonly used for uploading files in Node.js applications. With Multer, you can easily manage receiving, storing, and validating files on the server. File-Saver is a JavaScript library that enables dynamic file downloads directly from the browser, allowing users to save files without leaving the application. Together, these tools efficiently manage both file uploads and downloads, providing a smooth experience for users interacting with files in your app.
Real-Time Notifications with Socket.IO
Implementing real-time features like notifications using Socket.IO was a challenging yet rewarding experience. I navigated concepts like socket.on
, socket.emit
, and room management. Deploying this on a live server was another hurdle, requiring specific configurations for seamless functionality. Using settings like:
Polling: It is a communication method where the client repeatedly sends HTTP requests at regular intervals to the server to check for updates, rather than keeping a persistent connection open. This is typically used when WebSockets are not available or suitable.
Reconnection: Enables automatic reconnection in case of network interruptions or connection loss, ensuring better reliability for real-time communication.
These settings were part of the frontend, enabling a smooth connection with the backend logic on a live server.
Reflections and Growth
Backend development was never my comfort zone, but the journey transformed it into a valuable skill set. From struggling with basic setups to implementing advanced features, every challenge taught me resilience and problem-solving. Today, I see backend as a critical part of creating seamless, full-stack applications. The road wasn’t easy, but the results were worth every effort. To all the budding developers out there, when you finally see the results of your hard work, combining both frontend and backend, it is all worth it. To sail through and reach your destination, you need to experience the tides and storms.
Keep learning, keep growing, and remember: even the most confusing parts of coding eventually make sense with persistence and practice!
Happy DevLogging! <3
~s.b.m.
#WomenWhoTech#SerialBlogger#Backend#Development#NodeJS#API#ExpressJS#2Articles1Week#Hashnode#Tech#Enthusiast