📢 Notice 📢

5 minute read

Notes from the COMP3011 Web App Frameworks assignment 3.

Overview

This is a full-stack blog management system built with a Node.js and Express backend, a MongoDB database, and a React.js single-page application frontend. This project was upgraded from a previous blog app, server-side rendered Pug application to a client-side rendered React application to implement a real-time notification system using Socket.io.

Tech Stack

  • Backend: Node.js, Express, Socket.io, Passport.js, Joi, Bcrypt
  • Frontend: React.js, Vite, React-Bootstrap, Socket.io-client, Axios
  • Database: MongoDB with Mongoose

Thought process and approach

The primary goal was to upgrade a classic server-side rendered application into a modern, interactive, and real-time MERN stack Single-Page Application (SPA). The approach was centered on creating a clean separation between the backend API and the client-side React UI, while integrating a real-time layer for a dynamic user experience.

  1. Frontend Architecture: Migrating to a React SPA
    I decided to completely decouple the frontend from the backend, creating a pure client-side application with React. This approach allows for a faster, more fluid user experience without full-page reloads. I used Vite for the build tooling and React-Bootstrap for a responsive component library. The core routing was handled by React Router, with all routes defined in frontend/src/App.jsx.

  2. Component-Based Design
    To ensure the frontend was maintainable and scalable, I adopted a component-based architecture.
    • Page Components (frontend/src/pages/): Each component, like Home.jsx or PostDetail.jsx, corresponds to a specific route.
    • Reusable UI Components (frontend/src/components/): Components like NavigationBar.jsx and PostCard.jsx were designed to be reusable across different pages, promoting consistency and reducing code duplication.
  3. State Management Strategy with React Context
    Different types of state required different management strategies:
    • Local State: Managed with useState for component-specific data like form inputs (e.g., in Login.jsx and PostEditor.jsx).
    • Global State: Managed with React Context API:
      • AuthContext – Tracks login state and persists session info in localStorage.
      • NotificationContext – Handles real-time notifications.
      • PresenceContext – Manages currently online users.
  4. Real-Time Integration with Socket.IO
    A key requirement was real-time functionality. I implemented a centralized Socket.IO module on both the frontend and backend.
    • Backend (backend/sockets/index.js): Authenticates socket connections with Express sessions. Tracks active user connections using socketsByUser to support multiple tabs and manage the “Active Users” feature.
    • Frontend: A single socket instance is created in frontend/src/services/socket.js and shared via SocketContext.
  5. Data Flow and API Communication
    REST API communication is centralized through frontend/src/services/api.js using Axios. Pages fetch backend data via useEffect, store in local useState, and re-render accordingly.

Key Learnings

React Hooks (useState, useEffect, useContext)

This project solidified my understanding of core React Hooks:

  • useState for local state
  • useEffect for API calls and socket subscriptions
  • useContext for consuming global contexts like AuthContext and PresenceContext

I also created a custom hook useAuth for reusing auth logic easily.

SPA Routing with React Router

Defined the full routing structure in App.jsx. I created a PrivateRoute component to protect routes (e.g., /new, /subscriptions) based on login state via AuthContext.

Full-Stack State Synchronization

Learned to synchronize state between the frontend (localStorage, Context), and backend (Express sessions in MongoDB). Used Socket.IO to broadcast session updates across tabs for real-time syncing.

Real-Time Communication with Socket.IO

Built a real-time system by:

  • Authenticating socket connections
  • Broadcasting updates (io.emit)
  • Reacting to events on the frontend (socket.on)

This powered both the live notification system and active user list.

Component-Based Architecture

Migrating from Pug templates to React taught me the power of reusable components. By modularizing the UI into units like PostCard.jsx and NavigationBar.jsx, development became faster and cleaner. Integrating React-Bootstrap further streamlined styling and layout.

Reflection

This full-stack React blog app was a very challenging yet rewarding project due to its scale and complexity. While I had previous experience with Django and simple Node.js applications using Pug templates, this project required a much deeper understanding of full-stack development. I had to manage extensive API integration between the frontend and backend and master core React concepts such as props, parent-child component relationships, and Hooks.

As a computer science student, I believe selecting this as an elective unit was an excellent choice, even though it is not one of my core subjects. I really enjoyed the entire learning journey. The professor’s teaching style was particularly effective, instead of simply reading from lecture slides, he fostered a communicative environment and made a dedicated effort to ensure every student understood the fundamental concepts.

Building this application gave me a profound appreciation for why development work is often separated into specialized roles like frontend and backend. I now understand that as a web service grows in scale, managing the entire stack alone becomes incredibly difficult. This project highlighted the importance of a modular and separated architecture for maintainability.

While I recognize there’s still much more to learn about React and other industry-standard frameworks, this experience has given me a strong foundation in modern web application architecture. It has been a valuable milestone in my growth as a developer.

Extra notes RESTful APIs

REST (Representational State Transfer) is an architectural style used for designing networked applications, especially web services. RESTful web services are:

  • Highly scalable
  • Lightweight
  • Easy to maintain

They are commonly used to build APIs for web-based applications.

HTTP Methods in REST

In RESTful services, HTTP provides several methods to manipulate resources. The most commonly used methods for data creation and modification are:

POST

  • Purpose: To submit a new entity to a resource.
  • Use Case: Creating a new resource under a collection.
  • Effect: May result in a new resource being created, or the server performing some action.

PUT

  • Purpose: To update a resource, or create it if it does not exist.
  • Use Case: Full replacement of a resource at a specific URL.
  • Effect: If the resource exists, it is replaced; if not, a new one is created.

PATCH

  • Purpose: To partially update a resource.
  • Use Case: Modify only specific fields of a resource without replacing the entire object.
  • Effect: Applies a partial change to the resource.

Summary Table

Method Purpose Creates Resource Updates Resource Partial Update
POST Submit new data
PUT Create or replace ✅ (full)
PATCH Update part of data ✅ (partial)

Leave a comment