Skip to main content

Docs - Backend

Published 13 min readMarkdown

cookie-parser

Parse Cookie header and populate req.cookies with an object keyed by the cookie names. Optionally you may enable signed cookie support by passing a secret string, which assigns req.secret so it may be used by other middleware.

npm i cookie-parser
var cookieParser = require('cookie-parser')

cookieParser(secret, options)

Create a new cookie parser middleware function using the given secret and options.

  • secret a string or array used for signing cookies. This is optional and if not specified, will not parse signed cookies. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.

  • options an object that is passed to cookie.parse as the second option. See cookie for more information.

    • decode a function to decode the value of the cookie

parse:

means example url contains many information like username, password , so decoding it in an object format is called as parse

The middleware will parse the Cookie header on the request and expose the cookie data as the property req.cookies and, if a secret was provided, as the property req.signedCookies. These properties are name value pairs of the cookie name to cookie value.

When secret is provided, this module will unsign and validate any signed cookie values and move those name value pairs from req.cookies into req.signedCookies

1️⃣ What is JSON? (JavaScript Object Notation)

JSON (JavaScript Object Notation) is a lightweight data format used for storing and exchanging data between a server and a client (like a web browser or mobile app).

✅ Key Features of JSON:

  • Uses key-value pairs ("name": "John").

  • Lightweight & easy to read.

  • Data is structured like JavaScript objects but can be used in almost any programming language.

  • Often used for APIs and configuration files.

✅ Example of JSON Data:

jsonCopyEdit{
    "name": "Alice",
    "age": 25,
    "email": "alice@example.com",
    "hobbies": ["reading", "coding", "gaming"]
}

JSON is widely used for API responses, database storage, and configuration files (package.json).


2️⃣ What is NPM (Node Package Manager)?

NPM (Node Package Manager) is a tool used to install, manage, and share JavaScript packages (libraries) in Node.js.

✅ Key Features of NPM:

  • Comes pre-installed with Node.js.

  • Lets you install, update, and remove JavaScript packages.

  • Uses package.json to track dependencies.

JWT - Json web Token

npm i jsonwebtoken

Difference Between URI and URL

  • URL (Uniform Resource Locator): The complete web address that includes the protocol (e.g., https://api.example.com/books?title=Harry Potter).

  • URI (Uniform Resource Identifier): A broader term that includes URLs and URNs (Unique Resource Names). A URI component refers to a part of the URI (like a query parameter).

When to Use encodeURIComponent()

You use encodeURIComponent() to safely encode query parameters in a URL. This prevents issues with special characters like spaces, &, ?, and =.

Example Without Encoding (Incorrect)

javascriptCopyEditconst title = "Harry Potter & the Philosopher's Stone";
const url = `https://api.example.com/books?title=${title}`; 
console.log(url);

Output (Incorrect URL)

arduinoCopyEdithttps://api.example.com/books?title=Harry Potter & the Philosopher's Stone

Since & is a special character in URLs, the API might misinterpret it.

Correct Way Using encodeURIComponent()

javascriptCopyEditconst title = "Harry Potter & the Philosopher's Stone";
const encodedTitle = encodeURIComponent(title);
const url = `https://api.example.com/books?title=${encodedTitle}`;
console.log(url);

Output (Correct URL)

perlCopyEdithttps://api.example.com/books?title=Harry%20Potter%20%26%20the%20Philosopher%27s%20Stone

Now, special characters like spaces (%20) and & (%26) are properly encoded.

When to Use encodeURI() Instead

If you need to encode a full URL (excluding query parameters), use encodeURI(), which leaves the ? and & characters intact.

javascriptCopyEditconst url = "https://api.example.com/books?title=Harry Potter & the Philosopher's Stone";
console.log(encodeURI(url));

This will encode spaces but not ? or &.

Summary

  • Use encodeURIComponent() for query parameters (e.g., title, author).

  • Use encodeURI() for a full URL if it contains unsafe characters.

1. Is This a URL?

Yes! The following is a URL (Uniform Resource Locator):

arduinoCopyEdithttps://api.example.com/books?title=Harry Potter

A URL locates a resource (like a webpage or API data) on the internet.


2. Does a URL Contain a Route?

Yes! The route is the part of the URL that specifies what resource you want.
In this URL:

arduinoCopyEdithttps://api.example.com/books?title=Harry Potter
  • https:// → Protocol (How we access the resource)

  • api.example.com → Domain (Server) hosting the API

  • /books → Route (Endpoint) to get book data

  • ?title=Harry Potter → Query parameter (filters results)

So, routes exist inside URLs and guide the API to fetch specific data.


3. Does "api" in the URL Mean It's an API?

Not necessarily! The word "api" in the URL is just part of the domain name.
It’s common to name subdomains api.example.com to indicate an API, but the real API functionality is in the backend code (Node.js, Django, etc.).

Example:

Both can exist on the same server, but one provides data (API), and the other shows webpages.


4. Is "API" Predefined in Node.js?

No, "API" is not a predefined keyword in Node.js.

  • The API logic is written by developers using frameworks like Express.js.

  • The URL just calls the API; Node.js processes the request in the backend.

Example of how an API is created in Node.js with Express:

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

// Defining an API route
app.get("/books", (req, res) => {
  res.json([
    { title: "Harry Potter", author: "J.K. Rowling" },
    { title: "The Hobbit", author: "J.R.R. Tolkien" }
  ]);
});

app.listen(3000, () => console.log("API running on port 3000"));

Now, when you visit:

bashCopyEdithttp://localhost:3000/books

It returns:

jsonCopyEdit[
  { "title": "Harry Potter", "author": "J.K. Rowling" },
  { "title": "The Hobbit", "author": "J.R.R. Tolkien" }
]

So, Node.js provides the API logic, but the word "api" in the URL is just a convention!

✅ We use await for fetch() and .json() because they return promises.
❌ We don’t need await for displayBooks() because it runs synchronously.

fetch api in two way:

1st:

fetch("https://www.thecocktaildb.com/api/json/v1/1/random.php") .then((response) => { if (response.ok) { return response.json(); } else { throw new Error("NETWORK RESPONSE ERROR"); } }) .then(data => { console.log(data); displayCocktail(data) }) .catch((error) => console.error("FETCH ERROR:", error));

2nd:

async function fetchBooks() {

try {

const response = await fetch("https://api.freeapi.app/api/v1/public/books"); // Fixed API URL

if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);

const data = await response.json();

books = data.data.books; // Adjust based on actual API response structure

displayBooks(books);

} catch (error) {

console.error("Error fetching data:", error);

}

}

API FETCH:-

Great question! The reason we did not use async/await in this code is because we used .then() and .catch() instead.

Both approaches (async/await and .then()) handle asynchronous operations, but they do so in different ways. Let’s break it down.


1. .then() and .catch() (Promise Chain)

In your code, you're handling the API request using promise chaining with .then():

javascriptCopyEditfetch("https://www.thecocktaildb.com/api/json/v1/1/random.php")
  .then((response) => {  // First "then"
    if (response.ok) {
      return response.json(); // Returns a promise
    } else {
      throw new Error("NETWORK RESPONSE ERROR");
    }
  })
  .then(data => {  // Second "then"
    console.log(data);
    displayCocktail(data);
  })
  .catch((error) => console.error("FETCH ERROR:", error));  // Handles errors
  • ✅ Fetch request starts (returns a promise)

  • ✅ .then(response => response.json()) waits for the response and extracts JSON

  • ✅ .then(data => displayCocktail(data)) runs after the JSON is parsed

  • ✅ .catch(error) handles any errors

This works because .then() automatically chains promises and ensures each step waits for the previous one.


2. async/await Approach

The equivalent async/await version looks like this:

javascriptCopyEditasync function fetchCocktail() {
    try {
        const response = await fetch("https://www.thecocktaildb.com/api/json/v1/1/random.php");
        if (!response.ok) throw new Error("NETWORK RESPONSE ERROR");

        const data = await response.json();
        console.log(data);
        displayCocktail(data);
    } catch (error) {
        console.error("FETCH ERROR:", error);
    }
}

fetchCocktail();

Here’s why async/await works:

  • ✅ await fetch() waits for the response

  • ✅ await response.json() waits for the JSON to be parsed

  • ✅ Errors are caught in the try/catch block


3. Why Use .then() Here Instead of async/await?

  • JavaScript Promises allow both .then() and async/await

  • Both methods work, and which one you use depends on coding style

  • .then() is older but still valid, while async/await makes code more readable

  • Your example is using promise chaining, while the previous API example used async/await for clarity


4. Which One Should You Use?

✅ Use .then() if:

  • You are comfortable with promise chaining

  • Your codebase already follows this pattern

  • You prefer explicit error handling with .catch()

✅ Use async/await if:

  • You want cleaner, more readable code

  • You’re working with multiple async functions

  • You need try/catch for better error handling


Final Answer

Both approaches work, but the reason we used .then() here is that the original code was written using promise chaining.
We used async/await in the previous API call because it was a different coding style.

Would you like me to rewrite your cocktail API code using async/await for consistency? 🚀

4o

You said:

yes

ChatGPT said:

Here's your cocktail API code rewritten using async/await for better readability and consistency:

Updated Code:

javascriptCopyEditasync function fetchCocktail() {
    try {
        const response = await fetch("https://www.thecocktaildb.com/api/json/v1/1/random.php");

        if (!response.ok) throw new Error("NETWORK RESPONSE ERROR");

        const data = await response.json();
        console.log(data);

        displayCocktail(data);
    } catch (error) {
        console.error("FETCH ERROR:", error);
    }
}

// Call the function
fetchCocktail();

Why is this better?

✅ More readable than .then() chaining
✅ Uses try/catch for better error handling
✅ Consistent with your other async/await API calls

For scalability and performance in your Amazon-like e-commerce management system, you need a well-architected backend that can handle high traffic, multiple transactions, and data consistency. Here's how you can achieve that:


1. Use Microservices Architecture

Instead of a monolithic system where all features (users, products, orders, payments, etc.) exist in a single backend, break it into microservices, each handling a specific function.

  • User Service → Handles authentication, user profiles (buyers & sellers)

  • Product Service → Manages product listings, categories, inventory

  • Order Service → Processes orders, cart, checkout, shipping

  • Payment Service → Handles payments, transactions, refunds

  • Warehouse Service → Tracks stock, warehouse locations

  • Notification Service → Sends emails, SMS, push notifications

Technology Choice:

  • Backend: Node.js (Express, NestJS) / Django / Spring Boot

  • Communication: REST APIs / gRPC / Message Queues (RabbitMQ, Kafka)

  • API Gateway: Kong API Gateway / Nginx / AWS API Gateway


2. Implement Caching for Fast Access

Use Redis or Memcached to store frequently accessed data, reducing database load.

What to Cache?

  • Product Listings → Popular items, search results

  • User Sessions → JWT tokens, user preferences

  • Order Summaries → Frequently accessed order details

Example: Cache product details for 10 minutes using Redis:

bashCopyEditSETEX product_123 600 '{ "name": "iPhone 15", "price": 999 }'

3. Load Balancing for High Traffic

Distribute incoming requests across multiple servers using Load Balancers like:

  • Nginx (Open-source, customizable)

  • AWS Elastic Load Balancer (ELB) (Auto scales with traffic)

  • HAProxy (Good for high performance)

Example: If 10,000 users are shopping, the load balancer will direct traffic evenly across multiple backend servers.


4. Asynchronous Processing for Heavy Tasks

For time-consuming tasks like order processing, payments, and notifications, use message queues instead of making users wait.

  • Kafka / RabbitMQ → Handles tasks in the background.

  • Example Use Cases:

    • Order placed → Send payment request to Payment Service

    • Payment completed → Notify Warehouse Service to pack and ship order

    • Order shipped → Send SMS/email update to customer

Example: Using Kafka in Node.js

javascriptCopyEditconst { Kafka } = require('kafkajs');
const kafka = new Kafka({ clientId: 'ecommerce', brokers: ['kafka1:9092'] });
const producer = kafka.producer();

async function sendOrderMessage(orderData) {
  await producer.connect();
  await producer.send({
    topic: 'order_created',
    messages: [{ value: JSON.stringify(orderData) }],
  });
}

5. Database Optimization

For a huge dataset (millions of users, orders, products, etc.), use:

  1. Partitioning & Sharding

    • Split database tables based on regions (e.g., US, Europe) or categories (e.g., Electronics, Fashion).

    • Example: A "Products" table with Partition 1 = Electronics, Partition 2 = Clothing.

  2. Read-Replicas for Scaling Reads

    • Use primary DB for writes and read replicas for search operations.

    • Example: A MySQL master-slave setup where queries are split efficiently.

  3. NoSQL for High-Speed Reads

    • Use MongoDB / DynamoDB for product listings, user sessions.

    • Use PostgreSQL / MySQL for structured data (orders, payments).


6. CDN for Faster Content Delivery

Store product images, banners, and videos in a Content Delivery Network (CDN) to load them faster.

  • Cloudflare / AWS CloudFront / Akamai

  • Example: Instead of loading images from a central server, a CDN caches them globally for fast access.


7. Auto-Scaling to Handle Traffic Spikes

If your e-commerce platform has flash sales (e.g., Black Friday), use auto-scaling to prevent downtime.

  • Kubernetes (K8s) → Auto-scales microservices

  • AWS Auto Scaling → Adds more instances dynamically

  • Docker Containers → Run services in isolated environments

Example: If 10,000 new users enter within 1 minute, auto-scaling will spin up more backend instances to handle the load.


8. Monitoring & Logging for Debugging

Use real-time monitoring tools to track system health:

  • Prometheus + Grafana → Dashboard for CPU, memory, and requests

  • ELK Stack (Elasticsearch, Logstash, Kibana) → Logs errors, crashes

  • Datadog / AWS CloudWatch → Monitors API latency, database queries

Example: If orders are failing due to slow database queries, Grafana will alert you.


Final Architecture Diagram

🟢 Frontend (React / Next.js / Vue.js)
⬇️ API Gateway (Nginx / Kong)
⬇️ Microservices (User, Order, Payment, Warehouse, Notification)
⬇️ Databases (PostgreSQL, MongoDB, Redis for cache)
⬇️ Queue System (Kafka, RabbitMQ)
⬇️ Warehouse & Shipping APIs (DHL, FedEx, UPS)


Conclusion

For an Amazon-like scalable system, you need: ✅ Microservices to split functionality
✅ Caching (Redis, CDN) for speed
✅ Load Balancing & Auto-Scaling for high traffic
✅ Database Optimization to handle millions of records
✅ Asynchronous Processing for efficiency
✅ Monitoring & Logging to track performance

🔐 Why Use These Tokens?

Token TypePurposeExpiry TimeWhere to Store?Security Level
Access TokenAPI authenticationShort (e.g., 1 hour)Client-side (LocalStorage, etc.)Medium
Refresh TokenIssue new access tokensLong (e.g., 7 days)HTTP-only cookiesHigh
Temporary TokenPassword reset, email verificationShort (e.g., 20 min)Stored temporarily in DBHigh

A cookie is a small piece of data stored in the user's browser by a website. It helps websites remember users and store small amounts of data between visits.

🔥 Why Are Cookies Used?

✅ Store authentication tokens (e.g., JWT refresh tokens).
✅ Save user preferences (e.g., dark mode, language settings).
✅ Track session data (e.g., shopping cart items, login status).
✅ Help in analytics & tracking (e.g., remembering visited pages).


🔐 Why Do Cookies Store Sensitive Data?

Cookies are often used to store sensitive information (like authentication tokens) because:

  1. They Persist Between Requests → Unlike localStorage, cookies are automatically sent with every request to the server.

  2. Secure Storage for Refresh Tokens → HTTP-only cookies prevent JavaScript from accessing sensitive data.

  3. Session Management → Websites use cookies to keep users logged in even after they close the browser.


❌ Security Risks of Cookies

1️⃣ XSS (Cross-Site Scripting) Attack

  • If an attacker injects malicious JavaScript, they can steal cookies.

  • Solution: Use httpOnly: true so JavaScript cannot access the cookie.

2️⃣ CSRF (Cross-Site Request Forgery) Attack

  • If a cookie is automatically sent with requests, attackers can trick users into performing unwanted actions.

  • Solution: Use CSRF tokens and sameSite: "Strict" to prevent unauthorized requests.

3️⃣ Session Hijacking

  • If a refresh token is stolen, attackers can generate new access tokens.

  • Solution: Use short-lived access tokens and require re-authentication after refresh tokens expire.


✅ How to Secure Cookies?

When storing sensitive data, use secure cookie options:

jsCopyEditres.cookie("refreshToken", token, {
  httpOnly: true,  // Prevents JavaScript access (XSS protection)
  secure: true,    // Only sends cookie over HTTPS
  sameSite: "Strict", // Prevents CSRF attacks
  maxAge: 7 * 24 * 60 * 60 * 1000, // Expiration time (7 days)
});
OptionPurposePrevents
httpOnly: trueJavaScript cannot access the cookieXSS attacks
secure: trueOnly send over HTTPSMan-in-the-middle attacks
sameSite: "Strict"Prevents sending cookies on cross-site requestsCSRF attacks
maxAge: 604800000Controls expiration (in milliseconds)Stale cookies

🔑 Summary

✔ Cookies store authentication tokens & session data
✔ Secure cookies properly to prevent attacks (XSS, CSRF)
✔ Use httpOnly, secure, and sameSite: "Strict" for protection

About the author

  • 💻 Software Developer | 🚀 Building next-gen digital platforms 🔭 Currently working on a fan-influencer interaction startup 💡 Passionate about scalable systems, DSA, system design & product thinking 📚 Electrical Engineering @NIT JSR | 2nd Year ✨ Learning in public | Sharing my journey in tech & startups

No comments yet. Be the first to comment.