Skip to content

Juadebfm/august_fullstack_web_app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction to Backend Development

What is a Backend and Why Do We Need It?

Imagine your favorite online store. The frontend is what you see—the beautiful interface, buttons, images, and product listings. But how does it know which products to show, or how does it process your payment? This is where the backend comes in.

Definition: The backend is the engine of a web application, working behind the scenes to:

  • Store and organize data.
  • Process user actions (like logging in or placing an order).
  • Ensure the application runs smoothly and securely.

Key Roles of a Backend:

  • Data Storage: Keeps all data organized in a database (e.g., user accounts, product details, etc.).
  • Processing Requests: Handles tasks like verifying login credentials or calculating prices.
  • Security: Ensures data is safe and accessible only to authorized users.
  • Communication: Connects the frontend to databases, APIs, or other systems.

Client-Server Architecture Basics

Think of a client-server architecture as a conversation:

  • Client: The one asking questions (browser, mobile app).
  • Server: The one answering the questions (backend).

How it Works:

The client sends a request to the server (e.g., "Give me all the available books").

The server:

  • Reads the request.
  • Retrieves the necessary data (from its own logic or a database).
  • Sends back a response (e.g., "Here’s the list of books").
  • The client displays this information to the user.

Analogy:

  • The client is like a customer in a restaurant.
  • The server is the waiter.
  • The database is the kitchen where food (data) is prepared.
  • The process of the waiter taking an order and delivering food is like the backend managing requests and responses.

How Frontend and Backend Communicate:

  • Communication Medium: HTTP (HyperText Transfer Protocol)
  • HTTP is like a language both frontend and backend understand.
  • Frontend sends an HTTP request to the backend (e.g., "Show me all the posts").
  • Backend replies with an HTTP response containing the requested data (e.g., JSON with post details).

Parts of an HTTP Request:

  • URL: Address of the resource being requested.
  • Example: https://example.com/api/posts.
  • Method: Type of action to perform (GET, POST, etc.).
  • Headers: Additional information (e.g., authentication tokens).
  • Body: Data sent with the request (used in POST, PUT).

Example Workflow:

  • User opens a web page.
  • Frontend: "Hey server, I want to log in. Here’s my email and password." -> Backend:
  • Checks if the email and password are correct.
  • Sends a response: "Welcome back! Here’s your user info."

Introduction to APIs and HTTP Methods

What is an API?

API stands for Application Programming Interface. It’s like a contract between two systems. The frontend says, “I’ll ask you these types of questions,” and the backend replies, “I’ll give you answers in this specific format.”

Analogy:

Imagine a waiter at a restaurant as the API. You (frontend) tell the waiter what you want to order. The waiter communicates this to the kitchen (backend) and brings back the prepared food. The waiter (API) ensures that the kitchen (backend) and you (frontend) speak the same language and follow the same rules.

Why APIs?

  • They allow communication between different systems or applications.
  • They ensure consistency—every frontend user gets data in the same structure.

HTTP Methods Explained:

GET:

Purpose: To fetch data. Example: When you visit a blog, the frontend sends a GET request to retrieve the blog posts. Analogy: Asking for a menu at a restaurant.

POST:

Purpose: To send data to the server, usually to create something new. Example: Submitting a registration form to sign up for an account. Analogy: Placing an order at a restaurant.

PUT:

Purpose: To update an existing resource. Example: Updating your profile picture. Analogy: Changing an order before it’s prepared.

DELETE:

Purpose: To remove a resource. Example: Deleting a post you made on a forum. Analogy: Sending a dish back to the kitchen and asking it to be removed from your bill.

Example of API in Action: You open a weather app, which shows today’s temperature.

Frontend: Sends a GET request to the weather API (e.g., "What’s the weather in London?").

Backend: Looks up the temperature for London in its database and responds with JSON:

{
  "location": "London",
  "temperature": "12°C",
  "condition": "Cloudy"
}

Frontend: Displays this data to the user.

Node.js Fundamentals

What is Node.js?

Node.js is a runtime environment that allows you to run JavaScript code outside of a browser. Think of it as a way to use JavaScript on your computer or server instead of just in web pages.

Why Node.js?

  • Fast and Efficient: Built on Chrome’s V8 JavaScript engine, Node.js is designed to be fast.
  • Non-blocking: Node.js uses an event-driven, non-blocking I/O model, making it ideal for building scalable applications.
  • Single Programming Language: Use JavaScript for both frontend and backend, which simplifies development.
  • Vast Ecosystem: With npm (Node Package Manager), you can access thousands of libraries to speed up development.

Installing Node.js and Understanding npm

How to Install Node.js:

  1. Go to the official Node.js website

    • Go to (Node.js)[https://nodejs.org/en/download/] Official Website.
    • Download the LTS version (Long-Term Support) for stability.
    • Follow the installation steps for your operating system.
  2. Verify Installation:

    • Open your terminal and type:
    node -v

    This shows the installed Node.js version.

What is npm?

npm stands for Node Package Manager. It’s a tool that comes with Node.js, allowing you to:

  • Install libraries or packages.
  • Manage dependencies for your project.

Basic npm Commands:

  • Initialize a Project:
npm init

This creates a package.json file to manage your project’s dependencies.

  • Install a Package:
npm install <package-name>

Example: To install Express.js:

npm install express

Install Packages Globally:

npm install -g <package-name>

Use this for tools you want to use from anywhere on your computer.

Basic JavaScript Concepts Review (If Needed)

Before diving into Node.js, ensure you’re comfortable with these concepts:

Variables:

let name = "John"; // Changeable
const age = 30; // Constant

Functions:

function greet() {
  return "Hello!";
}
console.log(greet());

Objects and Arrays:

const user = { name: "John", age: 30 };
console.log(user.name); // Accessing properties

const fruits = ["apple", "banana"];
console.log(fruits[1]); // Accessing array items

Asynchronous Programming: Using setTimeout or Promises to handle tasks that take time, like reading files or fetching data.

Node.js Core Concepts

Modules:

Modules are like Lego blocks for your application. You can create your own modules or use existing ones. Node.js allows you to organize code into modules for better readability and reusability.

Example:

// math.js
function add(a, b) {
  return a + b;
}
module.exports = add;

// app.js
const add = require("./math");
console.log(add(2, 3)); // Outputs: 5

Event Loop:

The event loop allows Node.js to perform non-blocking operations. It works by listening for events and executing callbacks as they occur.

Example:

console.log("Start");
setTimeout(() => {
  console.log("Timeout finished");
}, 1000);
console.log("End");
Start
End
Timeout finished

Asynchronous Programming:

Node.js heavily relies on asynchronous code to handle tasks like reading files or querying a database without blocking other operations.

Here’s how to create your first server using the built-in http module:

Example:

const http = require("http");

// Create a server
const server = http.createServer((req, res) => {
  // Set the response header
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.end("Hello, world!"); // Send response
});

// Listen on a port
server.listen(3000, () => {
  console.log("Server running at http://localhost:3000/");
});

How It Works:

  • Import the http module.
  • Use http.createServer to create a server.
  • Define how the server should respond to requests.
  • Make the server listen on a specific port (e.g., 3000).

File System Operations

Node.js provides a built-in fs module to work with the file system.

Common File System Tasks:

  • Reading Files:
const fs = require("fs");
fs.readFile("example.txt", "utf8", (err, data) => {
  if (err) throw err;
  console.log(data);
});
  • Writing Files:
fs.writeFile("example.txt", "Hello, world!", (err) => {
  if (err) throw err;
  console.log("File written successfully");
});
  • Appending to a File:
fs.appendFile("example.txt", "\nNew line added!", (err) => {
  if (err) throw err;
  console.log("Content appended");
});
  • Deleting Files:
fs.unlink("example.txt", (err) => {
  if (err) throw err;
  console.log("File deleted");
});

Understanding package.json and node_modules

package.json:

It’s the configuration file for your Node.js project, containing:

  • Project metadata (name, version).
  • List of dependencies.
  • Scripts to run commands (e.g., npm start).

node_modules: A folder where all the installed packages are stored. Never modify it directly; instead, use npm to manage dependencies.

Express.js Framework

Why Use Express vs Plain Node.js?

Challenges with Plain Node.js:

While Node.js provides basic tools for creating servers, it can be repetitive and time-consuming to:

  • Handle routing (managing different URLs and HTTP methods).
  • Process requests and responses efficiently.
  • Deal with errors and middleware setup.

Benefits of Express.js:

  • Simplified Routing: Express makes it easy to define routes (URLs) for your app.
  • Middleware Support: It allows you to use middleware to process requests, like handling authentication or logging.
  • Flexibility: Works well with databases, templating engines, and other tools.
  • Popularity: A large community means lots of tutorials, plugins, and support.

Setting Up a Basic Express Server

Installation:

  • Ensure Node.js is installed.
    • Install Express using npm:
npm install express
  • Creating Your First Express Server:
const express = require("express");
const app = express(); // Initialize Express

// Define a route
app.get("/", (req, res) => {
  res.send("Hello, World!");
});

// Start the server
app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

What’s Happening?:

  • require('express'): Import the Express library.
  • app.get('/'): Define a route for the root URL (/) with a callback function to handle requests.
  • app.listen(3000): Start the server on port 3000.

Routing and Middleware Concepts

What is Routing?

Routing determines how an application responds to specific HTTP requests (GET, POST, etc.) made to a particular URL. Express provides several methods for defining routes, including app.get(), app.post(), app.put(), app.delete(), and more.

Example of Routing:

app.get("/about", (req, res) => {
  res.send("About Page");
});

app.post("/submit", (req, res) => {
  res.send("Form submitted");
});

What is Middleware?

Middleware functions are functions that have access to the request object (req), the response object (res), Middleware functions are like filters or tools that process requests before they reach the route handler.

Built-in Middleware in Express:

Static File Serving: Serve HTML, CSS, or JS files from a folder.

app.use(express.static("public"));
// Now you can access files in the 'public' folder

Parsing JSON:

app.use(express.json());
// Parses incoming JSON data from requests

Request and Response Objects

What are req and res?

  • req (request): Contains information about the incoming request (URL, query parameters, headers, etc.).
  • res (response): Allows you to send a response back to the client (text, JSON, HTML, etc.). Provides methods to send data back to the client.
app.get("/user", (req, res) => {
  console.log(req.query); // Access query parameters
  res.send("User information");
});

Handling Different HTTP Methods

Express makes it easy to define routes for various HTTP methods:

GET:

app.get("/products", (req, res) => {
  res.send("List of products");
});

POST:

app.post("/products", (req, res) => {
  res.send("Product added");
});

PUT:

app.put("/products/:id", (req, res) => {
  res.send(`Product with ID ${req.params.id} updated`);
});

DELETE:

app.delete("/products/:id", (req, res) => {
  res.send(`Product with ID ${req.params.id} deleted`);
});

Static File Serving

To serve static files like images, CSS, or JavaScript, you can use Express’s static middleware.

  • Create a folder named public and add an index.html file inside it.
  • Add this to your code:
app.use(express.static("public"));

Now, visiting http://localhost:3000/index.html will show the index.html file in your browser.

Error Handling in Express

To handle errors, you can define error-handling middleware:

Example:

app.use((err, req, res, next) => {
  console.error(err.stack); // Log the error
  res.status(500).send("Something broke!");
});

How It Works:

  • If an error occurs, Express skips normal route handlers and jumps to the error-handling middleware.

  • You can log errors, send user-friendly messages, or perform any cleanup tasks.

    APIs and REST

_ What is an API?_

API (Application Programming Interface): A way for software applications to communicate with each other. APIs allow different systems to exchange data and perform actions. APIs can be used to build web applications, mobile apps, and even IoT devices. APIs are typically built using HTTP (Hypertext Transfer Protocol) and JSON (JavaScript Object Notation). APIs can be categorized into two types: REST (Representational State of Resource) and SOAP (Simple Object Access Protocol). REST APIs are more popular and widely used. SOAP APIs are typically used for enterprise-level applications. It defines a set of rules (endpoints, methods, and responses) for interaction.

What is REST?

REST (Representational State of Resource) is an architectural style for designing networked applications. It is based on resources identified by URIs, manipulated using a fixed set of operations. REST is an acronym for Representational State of Resource. REST is an architectural style for designing networked applications.

What is RESTful API?

A RESTful API is an application program interface (API) that uses HTTP requests to interact with a server to read, create, update, or delete resources on the server following the REST architectural style.

What is RESTful API Design?

RESTful API design is the process of designing a RESTful API. It involves defining the resources, endpoints, methods, and responses for the API. RESTful API design is based on the REST architectural style.

What is SOAP SOAP (Simple Object Access Protocol) is a protocol for exchanging structured information in the implementation of web services. SOAP is a protocol for exchanging structured information in the implementation of web services.

Real-World Example (REST): Imagine a restaurant (Again):

  • The frontend is the menu you look at.
  • The backend is the kitchen preparing your order.
  • The API is the waiter who takes your order to the kitchen and brings your food back.

What is REST?

REST (Representational State Transfer): A set of architectural principles for designing APIs. RESTful APIs use HTTP methods and URLs to perform operations on resources.

Key Principles of REST:

  • Stateless: Every request from a client to a server must contain all the information needed. The server does not remember previous requests.
  • Resources: Data is treated as resources (e.g., users, products) and is accessed via endpoints like /users or /products.

HTTP Methods:

  • GET: Retrieve data.
  • POST: Create new data.
  • PUT: Update existing data.
  • DELETE: Remove data.

Uniform Interface: Use clear and consistent URLs for resources:

/products → List all products. /products/1 → Get details of product with ID 1. /products/1/orders → Get orders for product with ID 1. /products/1/orders/1 → Get details of order with ID 1 for product with ID 1.

Creating API Endpoints in Express

Example: Here’s how to set up a RESTful API for managing a list of tasks:

const express = require("express");
const app = express();

app.use(express.json()); // Middleware to parse JSON

let tasks = [
  { id: 1, title: "Learn Node.js", completed: false },
  { id: 2, title: "Build an API", completed: false },
];

// GET: Retrieve all tasks
app.get("/tasks", (req, res) => {
  res.json(tasks);
});

// GET: Retrieve a specific task
app.get("/tasks/:id", (req, res) => {
  const task = tasks.find((t) => t.id === parseInt(req.params.id));
  if (!task) return res.status(404).send("Task not found");
  res.json(task);
});

// POST: Add a new task
app.post("/tasks", (req, res) => {
  const newTask = {
    id: tasks.length + 1,
    title: req.body.title,
    completed: false,
  };
  tasks.push(newTask);
  res.status(201).json(newTask);
});

// PUT: Update a task
app.put("/tasks/:id", (req, res) => {
  const task = tasks.find((t) => t.id === parseInt(req.params.id));
  if (!task) return res.status(404).send("Task not found");

  task.title = req.body.title;
  task.completed = req.body.completed;
  res.json(task);
});

// DELETE: Remove a task
app.delete("/tasks/:id", (req, res) => {
  const taskIndex = tasks.findIndex((t) => t.id === parseInt(req.params.id));
  if (taskIndex === -1) return res.status(404).send("Task not found");

  tasks.splice(taskIndex, 1);
  res.status(204).send();
});

// Start the server
app.listen(3000, () => {
  console.log("API running at http://localhost:3000");
});

Route Parameters and Query Strings

Route Parameters:

Dynamic parts of a URL used to identify resources.

Example: /tasks/:id

app.get("/tasks/:id", (req, res) => {
  const id = req.params.id; // Access route parameter
  res.send(`Task ID: ${id}`);
});

Query Strings:

Additional parameters appended to the URL.

Example: /tasks?completed=true

app.get("/tasks", (req, res) => {
  const completed = req.query.completed; // Access query parameter
  res.send(`Tasks with completed = ${completed}`);
});

CORS and Security Basics

What is CORS?

CORS (Cross-Origin Resource Sharing) is a security feature in browsers that blocks requests made from a different domain or port.

Enabling CORS in Express:

Install the cors package:

npm install cors

Add it to your app:

const cors = require("cors");
app.use(cors());

Security Best Practices:

  • Use environment variables to store sensitive information (e.g., API keys).
  • Validate and sanitize user input to prevent attacks like SQL Injection.
  • Use HTTPS in production to encrypt data in transit.

MongoDB Basics

What is MongoDB?

MongoDB is a NoSQL database that stores data in a flexible, JSON-like format called BSON (Binary JSON). Unlike relational databases (like MySQL or PostgreSQL), it doesn’t use tables, rows, or columns. Instead, it organizes data into collections and documents.

Key Features of MongoDB

  • Flexible Schema: No fixed structure for data; each document can have different fields.
  • Scalable: Handles large amounts of data and high traffic easily.
  • Fast: Querying is optimized for unstructured or semi-structured data.
  • Rich Query Language: Supports powerful queries like filters, aggregations, and joins.
  • Cross-Platform: Runs on Windows, macOS, and Linux.

Key Concepts

Database: A container for collections.

Example: mydatabase

Collection: A group of related documents (like a table in SQL). Example: users, products

Document: A record in the database, stored as a JSON-like object. Example:

{
  "name": "Alice",
  "age": 25,
  "email": "alice@example.com"
}

Basic CRUD Operations

  1. Create (Insert Data) Insert a single document:
db.users.insertOne({
  name: "Alice",
  age: 25,
  email: "alice@example.com",
});

Insert multiple documents:

db.users.insertMany([
  { name: "Bob", age: 30, email: "bob@example.com" },
  { name: "Charlie", age: 35, email: "charlie@example.com" },
]);
  1. Read (Retrieve Data) Retrieve all documents:
db.users.find();

Retrieve documents with a filter:

db.users.find({ age: { $gt: 25 } }); // Find users older than 25

Retrieve specific fields:

db.users.find({}, { name: 1, email: 1 }); // Show only 'name' and 'email'
  1. Update Update a single document:
db.users.updateOne(
  { name: "Alice" }, // Filter
  { $set: { age: 26 } } // Update
);

Update multiple documents:

db.users.updateMany(
  { age: { $lt: 30 } }, // Filter
  { $set: { status: "active" } } // Update
);
  1. Delete Delete a single document:
db.users.deleteOne({ name: "Alice" });

Delete multiple documents:

db.users.deleteMany({ age: { $lt: 30 } });

MongoDB Atlas for Cloud Deployment

What is MongoDB Atlas? MongoDB Atlas is a cloud-hosted database service that allows you to easily deploy, manage, and MongoDB Atlas is a cloud-based database service that allows you to host your MongoDB databases online. Helps scale MongoDB databases in the cloud.

Why use MongoDB Atlas?

  • Easy deployment and management.
  • Scalability and high availability.
  • Security and compliance.
  • Cost-effective.

Steps to Use MongoDB Atlas:

  • Create an Account:
  • Sign up at MongoDB Atlas.
  • Create a Cluster:
    • Click "Create Cluster" and choose a free tier.
    • Connect to the Cluster:
  • Use the connection string provided (e.g., mongodb+srv://:@cluster0.mongodb.net/mydatabase).
    • Use in Code:
      • Install the MongoDB driver for Node.js:
npm install mongodb

Connect to the database:

const { MongoClient } = require("mongodb");
const uri = "your-mongodb-connection-string";

const client = new MongoClient(uri);

async function run() {
  try {
    await client.connect();
    console.log("Connected to MongoDB");
  } finally {
    await client.close();
  }
}

run().catch(console.dir);

Mongoose ODM

What is Mongoose?

Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js. It provides a structured way to define schemas for your data, perform validations, and interact with MongoDB using a more developer-friendly syntax.

Why Use Mongoose?

  • Schema Design: Mongoose allows you to define strict schemas for collections, ensuring consistent data.
  • Validation: Automatically validate data before saving it to the database.
  • Built-in Methods: Provides helper methods to simplify querying, updating, and deleting data.
  • Middleware: Execute code before or after certain database operations (e.g., pre-save hooks).
  • Relationships: Simplify references between collections.

Installing Mongoose

To use Mongoose in your Node.js project:

npm install mongoose

Connecting to MongoDB Here’s how to establish a connection to MongoDB using Mongoose:

const mongoose = require("mongoose");

// Replace with your MongoDB connection string
const uri = "mongodb://localhost:27017/mydatabase";

mongoose
  .connect(uri, {
    useNewUrlParser: true, // remove this coz it's currently deprecated
    useUnifiedTopology: true, // remove this coz it's currently deprecated
  })
  .then(() => console.log("Connected to MongoDB"))
  .catch((err) => console.error("Failed to connect to MongoDB:", err));

Defining a Schema

A schema in Mongoose defines the structure of a document.

const { Schema, model } = require("mongoose");

// Define a schema for a User
const userSchema = new Schema({
  name: { type: String, required: true }, // Name is required
  age: { type: Number, min: 0 }, // Age must be a positive number
  email: { type: String, unique: true }, // Email must be unique
  createdAt: { type: Date, default: Date.now }, // Default to current date
});
// Create a model
const User = model("User", userSchema);

Basic CRUD Operations with Mongoose

  1. Create (Insert Data)
   async function createUser() {
   const user = new User({
   name: 'Alice',
   age: 25,
   email: 'alice@example.com',
   })try {
   const savedUser = await user.save(); // Save to the database
   console.log('User created:', savedUser);
   } catch (err) {
   console.error('Error creating user:', err.message);
   }}
   createUser();
  1. Read (Retrieve Data)

Retrieve all users:

async function getUsers() {
const users = await User.find(); // No filter retrieves all documents
console.log('Users:', users);
}

getUsers();
Retrieve with filters:
javascript

async function findUserByName(name) {
const user = await User.findOne({ name });
console.log('User found:', user);
}

findUserByName('Alice');
  1. Update Update a single document:
async function updateUserEmail(userId, newEmail) {
  const updatedUser = await User.findByIdAndUpdate(
    userId,
    { email: newEmail },
    { new: true } // Return the updated document
  );
  console.log("Updated User:", updatedUser);
}

updateUserEmail("userIdHere", "newemail@example.com");
  1. Delete Delete a user:
async function deleteUser(userId) {
  const deletedUser = await User.findByIdAndDelete(userId);
  console.log("Deleted User:", deletedUser);
}

deleteUser("userIdHere");
  1. Data Validation Mongoose lets you enforce rules on your schema fields. For example:
const userSchema = new Schema({
  name: { type: String, required: true }, // Name is required
  age: { type: Number, min: 18, max: 65 }, // Age must be between 18 and 65
  email: {
    type: String,
    match: /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/, // Regular expression for email
  },
});

Middleware (Hooks)

Mongoose supports middleware, which lets you run functions before or after database operations.

Example: Pre-Save Middleware

userSchema.pre("save", function (next) {
  console.log("Before saving:", this);
  next(); // Call next to proceed
});

Relationships Between Collections

Mongoose allows you to reference documents in other collections using ObjectId.

Example: Referencing Another Collection

const postSchema = new Schema({
  title: { type: String, required: true },
  author: { type: Schema.Types.ObjectId, ref: "User" }, // Reference to User
});

const Post = model("Post", postSchema);
// Populate the author field
async function getPostsWithAuthors() {
  const posts = await Post.find().populate("author");
  console.log("Posts with authors:", posts);
}

getPostsWithAuthors();

Advanced Queries

Sorting:

User.find().sort({ age: -1 }); // Sort by age descending

Pagination:

User.find().skip(10).limit(10); // Skip the first 10 and limit to 10 results

Aggregation:

User.aggregate([{ $group: { _id: "$age", count: { $sum: 1 } } }]);

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published