Introduction: The Reception Desk of AQAD
Imagine AQAD has grown into a large B2B marketplace.
Every day:
- Vendors upload products
- Retailers place orders
- Logistic partners update deliveries
- Employees monitor operations
Now imagine there is no reception desk.
Customers arrive.
Nobody receives them.
Nobody understands their requests.
Nobody provides responses.
Chaos.
A backend server works very much like a reception desk.
It receives requests.
Processes them.
Returns responses.
This communication happens through something called:
HTTP
Before Node.js can become a real backend application, it must be able to:
- Accept requests
- Process requests
- Send responses
This chapter teaches exactly how that happens.
By the end of this chapter, you will understand how APIs and backend systems actually begin.
What Is HTTP?
HTTP stands for:
HyperText Transfer Protocol
Don't worry about memorizing the full form.
Think of HTTP as a language.
A language used by:
Browser
↔
Server
to communicate.
Real-Life Analogy
Imagine a customer enters a restaurant.
Customer:
Can I have a coffee?
Waiter:
Sure.
Kitchen prepares coffee.
Waiter returns:
Here is your coffee.
The conversation contains:
Request
Customer asking for something.
Response
Restaurant providing something.
HTTP works exactly the same way.
Understanding Client and Server
Every HTTP communication involves two parties.
Client
Requests information.
Examples:
- Browser
- Mobile App
- React Application
- React Native Application
Server
Provides information.
Examples:
- Node.js Backend
- Express API
- AQAD Backend
Example:
Retailer App
↓
Request Products
↓
AQAD Backend
↓
Return Products
What Happens When You Open a Website?
Suppose you visit:
https://aqad.com
Browser sends:
HTTP Request
Server processes it.
Server returns:
HTTP Response
Browser displays result.
This happens in milliseconds.
Creating Your First HTTP Server
Node.js includes a built-in module:
http
Import it:
const http = require('http');
No installation required.
Creating the Server
Example:
const http = require('http');
const server = http.createServer();
server.listen(3000);
Server now listens on:
http://localhost:3000
But it doesn't do anything yet.
Understanding createServer()
Think of:
http.createServer()
as opening the reception desk.
The desk exists.
But nobody is handling customers yet.
Handling Requests
Let's improve our server.
const http = require('http');
const server =
http.createServer(
(req, res) => {
res.end(
'Welcome to AQAD'
);
}
);
server.listen(3000);
Visit:
http://localhost:3000
Output:
Welcome to AQAD
Congratulations.
You built your first backend server.
Understanding req and res
Inside:
(req, res)
Node.js provides two objects.
req
Request Object.
Contains information sent by client.
res
Response Object.
Used to send information back.
Think of:
req as: Customer Request
and
res as: Restaurant Response
Understanding listen()
Example:
server.listen(3000);
Meaning:
Server
Listen on Port 3000
What Is a Port?
Think of a building.
One building.
Many doors.
Door 3000
Door 5000
Door 8080
Ports help computers identify services.
Common ports:
| Port | Purpose |
|---|---|
| 80 | HTTP |
| 443 | HTTPS |
| 3000 | Development |
| 5000 | APIs |
| 3306 | MySQL |
Adding a Startup Message
Useful for development.
server.listen(3000,() => {
console.log( 'Server Running');
}
);
Output:
Server Running
Accessing Request Information
Suppose user visits:
http://localhost:3000
Print request URL.
const server =
http.createServer(
(req, res) => {
console.log(
req.url
);
res.end('Hello');
}
);
Output:
/
Visit:
http://localhost:3000/products
Output:
/products
Interesting.
Now the server knows what page was requested.
Understanding Routing
Routing means:
Different URL
↓
Different Response
Example:
const server = http.createServer((req, res) => {
if(req.url === '/'){
res.end('Home Page');
}
}
);
Visit:
/
Output:
Home Page
Multiple Routes
Example:
const server = http.createServer((req, res) => {
if(req.url === '/'){
res.end('Home'); }
else if(req.url === '/products'){
res.end('Products');
}else{
res.end('Page Not Found' ); }
});
Visit:
/products
Output:
Products
AQAD Example
Imagine:
/products
/orders
/vendors
Each route returns different information.
Example:
if(req.url === '/products'){
res.end('Product List');
}
Understanding HTTP Methods
URL alone is not enough.
Clients also send methods.
Common methods:
| Method | Purpose |
|---|---|
| GET | Fetch data |
| POST | Create data |
| PUT | Update data |
| DELETE | Remove data |
GET Request
Retrieve information.
Example:
GET /products
Meaning:
Give me products.
POST Request
Create information.
Example:
POST /products
Meaning:
Create product.
Checking Request Method
Example:
console.log(req.method);
Output:
GET
AQAD Example
Retailer:
GET /products
Fetch products.
Vendor:
POST /products
Create product.
Returning HTML
Response can contain HTML.
Example:
res.end(`<h1>AQAD Marketplace</h1>`);
Browser displays:
AQAD Marketplace
as heading.
Returning JSON
Modern APIs mostly return JSON.
Example:
const products = [
{
id: 1,
name: 'Rice'
}
];
res.end(
JSON.stringify(products)
);
Output:
[
{
"id":1,
"name":"Rice"
}
]
Why JSON Is Important
Frontend applications understand JSON easily.
Examples:
- React
- React Native
- Angular
- Vue
All communicate using JSON.
Setting Response Headers
Headers provide metadata.
Example:
res.setHeader(
'Content-Type',
'application/json'
);
Then:
res.end(
JSON.stringify(data)
);
Browser now understands:
JSON Response
Understanding Status Codes
Every response includes a status.
Examples:
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request |
| 401 | Unauthorized |
| 404 | Not Found |
| 500 | Server Error |
Example
res.statusCode = 200;
res.end(
'Success'
);
Not Found Example
res.statusCode = 404;
res.end('Page Not Found');
Output:
404
AQAD API Example
if(req.url === '/products'){
res.statusCode = 200;
res.end('Products Found');
}
Unknown route:
res.statusCode = 404;
res.end('Not Found');
Building a Mini AQAD API
Example:
const http = require('http');
const server = http.createServer((req,res)=>{
if(req.url === '/products'){
const products = [
{
id:1,
name:'Rice'},
{
id:2,
name:'Milk'}
];
res.setHeader('Content-Type','application/json');
res.end(JSON.stringify(products));
}else{
res.statusCode = 404;
res.end('Route Not Found'); }
});
server.listen(3000);
Visit:
http://localhost:3000/products
Output:
[
{
"id":1,
"name":"Rice"
},
{
"id":2,
"name":"Milk"
}
]
Common Beginner Mistakes
Mistake 1
Forgetting res.end()
Bad:
res.write('Hello');
Without: res.end();
request never finishes.
Mistake 2
Ignoring Status Codes
Always return meaningful status codes.
Mistake 3
Sending Objects Directly
Bad:
res.end(products);
Good:
res.end(JSON.stringify(products));
Mistake 4
Not Setting Content-Type
JSON responses should use:
application/json
Mini Exercises
Exercise 1
Create:
/
route.
Return:
Welcome
Exercise 2
Create:
/products
route.
Return JSON.
Exercise 3
Print:
req.url
for every request.
Exercise 4
Return:
404 Not Found
for unknown routes.
Try It Yourself
Create:
const http =
require('http');
const server = http.createServer((req,res)=>{
res.statusCode = 200;
res.end('Hello AQAD');
});
server.listen(3000,()=>{
console.log('Server Running');
});
Run:
node app.js
Visit:
http://localhost:3000
Observe your first real backend response.
Interview Question
What is the difference between req and res in Node.js?
Good Answer:
The req object contains information sent by the client such as URL, method, and headers. The res object is used by the server to send responses back to the client including data, headers, and status codes.
Real Developer Insight
When beginners first create:
http.createServer()
it may look simple.
But behind this small function lies the foundation of:
- REST APIs
- Express.js
- Authentication systems
- Payment gateways
- E-commerce platforms
- Social media applications
Everything starts with understanding how a server receives requests and sends responses.
Once you understand HTTP servers, frameworks like Express become much easier because they are built on top of the same concepts.
Node.js Interview Questions and Real-World Scenarios
Introduction: Why Interview Preparation Matters
Imagine two developers applying for the same Node.js Backend Developer position.
Both have learned:
- JavaScript
- Node.js
- APIs
- Databases
Both can write code.
Both understand the basics.
But during the interview:
Developer A memorizes definitions.
Developer B explains:
- Why Node.js was created
- How the Event Loop works
- Why Streams improve performance
- How a production backend handles thousands of users
Which developer gets hired?
Usually Developer B.
Because companies don't hire developers who simply memorize answers.
They hire developers who understand how systems work.
The goal of this chapter is not to help you memorize interview answers.
The goal is to help you think like a backend developer.
We'll cover:
- Beginner questions
- Intermediate questions
- Advanced scenarios
- Real production examples
- AQAD marketplace case studies
Beginner-Level Questions
Question 1: What Is Node.js?
Answer:
Node.js is a JavaScript runtime environment built on Google's V8 Engine.
It allows JavaScript to run outside the browser and enables developers to build backend applications, APIs, command-line tools, and real-time systems.
Interview Tip
Don't say:
"Node.js is a programming language."
That is incorrect.
JavaScript is the language.
Node.js is the runtime.
Question 2: Why Was Node.js Created?
Answer:
Before Node.js, JavaScript mainly ran inside browsers.
Ryan Dahl created Node.js to allow JavaScript to run on servers and handle many concurrent connections efficiently using an event-driven, non-blocking architecture.
Question 3: What Is the V8 Engine?
Answer:
V8 is Google's JavaScript engine.
It converts JavaScript code into machine code so the computer can execute it quickly.
Node.js uses V8 to run JavaScript outside the browser.
Question 4: What Is NPM?
Answer:
NPM stands for Node Package Manager.
It helps developers install, manage, and share reusable packages.
It includes:
- Package registry
- Package manager
- CLI tool
Question 5: What Is package.json?
Answer:
package.json is the configuration file of a Node.js project.
It contains:
- Project information
- Dependencies
- Scripts
- Version details
- Metadata
Intermediate-Level Questions
Question 6: What Is the Event Loop?
Answer:
The Event Loop is the mechanism that allows Node.js to handle asynchronous operations without creating a new thread for every request.
It continuously checks:
Call Stack
Callback Queue
Microtask Queueand decides what should execute next.
Restaurant Analogy
Think of the Event Loop as a head waiter.
The waiter doesn't cook food.
The waiter coordinates activities and ensures tasks happen at the right time.
Question 7: What Is Non-Blocking I/O?
Answer:
Non-blocking I/O allows Node.js to start an operation and continue doing other work instead of waiting for the operation to finish.
Example:
fs.readFile(
'data.txt',
callback
);Node.js continues executing other code while the file is being read.
Question 8: What Is libuv?
Answer:
libuv is a C library used by Node.js.
It provides:
- Event Loop implementation
- Thread Pool
- Non-blocking I/O operations
libuv helps Node.js perform tasks such as:
- File operations
- DNS lookups
- Networking
Question 9: Difference Between require() and import?
require()
CommonJS
const fs =
require('fs');import
ES Modules
import fs
from 'fs';Modern projects increasingly use:
import
exportQuestion 10: What Are Environment Variables?
Answer:
Environment variables store configuration values outside the codebase.
Examples:
PORT
JWT_SECRET
DATABASE_URL
AWS_REGIONThey improve:
- Security
- Flexibility
- Deployment management
Event Loop Interview Questions
These questions appear frequently.
Question 11: Predict the Output
console.log('A');
setTimeout(() => {
console.log('B');
}, 0);
console.log('C');Output:
A
C
BWhy?
The timeout callback enters the callback queue.
Node.js executes synchronous code first.
Question 12: Predict the Output
console.log('Start');
Promise.resolve()
.then(() => {
console.log('Promise');
});
console.log('End');Output:
Start
End
PromiseWhy?
Promises use:
Microtask Queuewhich executes after synchronous code finishes.
Streams Interview Question
Question 13: Why Use Streams?
Answer:
Streams process data in chunks instead of loading entire files into memory.
Benefits:
- Lower memory consumption
- Better performance
- Improved scalability
Example
Bad:
fs.readFile()for huge files.
Better:
fs.createReadStream()Buffers Interview Question
Question 14: What Is a Buffer?
Answer:
A Buffer is a temporary memory area used to store raw binary data.
It is commonly used for:
- Files
- Streams
- Images
- Network communication
Modules Interview Question
Question 15: What Is Module Caching?
Answer:
When a module is loaded using:
require()Node.js stores it in memory.
Future requests use the cached version instead of reading the file again.
Benefits:
- Faster execution
- Better performance
Advanced Interview Questions
Question 16: Why Is Node.js Single-Threaded?
Answer:
Node.js uses a single-threaded event loop to simplify concurrency and reduce resource consumption.
However, Node.js is not limited to one thread.
libuv internally uses:
Thread Poolfor tasks like:
- File operations
- DNS lookups
- Cryptography
Question 17: Can Node.js Handle Thousands of Users?
Answer:
Yes.
Because Node.js uses:
- Event-driven architecture
- Non-blocking I/O
- Efficient resource utilization
it can handle many concurrent connections.
Example
Netflix and other large-scale companies have used Node.js for high-traffic systems.
Question 18: Difference Between process.nextTick() and setTimeout()
process.nextTick()
Runs before the next Event Loop phase.
setTimeout()
Runs during the Timers phase.
Example:
process.nextTick(() => {
console.log('Tick');
});
setTimeout(() => {
console.log('Timeout');
}, 0);Output:
Tick
TimeoutReal Production Scenarios
These questions test practical thinking.
Scenario 1
AQAD API Suddenly Becomes Slow
Symptoms:
High Response Time
Users Complaining
CPU Usage IncreasedWhat Would You Check?
Answer:
- CPU usage
- Memory usage
- Database performance
- Slow queries
- Application logs
- Network latency
Tools:
- CloudWatch
- PM2
- Grafana
- Node.js logs
Scenario 2
Memory Usage Keeps Increasing
Symptoms:
Application Starts Fine
Memory Grows Constantly
Eventually CrashesLikely Cause:
Memory LeakWhat To Investigate?
- Global variables
- Unclosed connections
- Cached data
- Event listeners
Scenario 3
Large CSV Upload Crashes Server
Vendor uploads:
5 GB CSVServer crashes.
Bad Solution:
fs.readFile()Better Solution:
fs.createReadStream()Use streams.
AQAD Marketplace Case Study
Let's combine everything.
Requirement
Retailer places order.
System must:
Save Order
Update Inventory
Notify Vendor
Send Email
Generate AnalyticsBeginner Solution
saveOrder();
updateInventory();
sendEmail();
notifyVendor();
analytics();Everything tightly coupled.
Better Solution
orderEmitter.emit(
'orderCreated'
);Listeners:
Inventory Service
Notification Service
Analytics Service
Email ServiceMore scalable.
System Design Style Question
How Would You Design Product Upload API?
Answer:
Step 1
Authentication
JWT verification.
Step 2
Validate request.
Step 3
Upload images.
Step 4
Store files.
S3 or file storage.
Step 5
Save product metadata.
Database.
Step 6
Emit event.
productCreatedStep 7
Update analytics.
Frequently Asked Node.js Interview Mistakes
Mistake 1
Saying:
Node.js is a programming language.
Wrong.
Mistake 2
Thinking:
setTimeout(fn, 0)runs immediately.
Wrong.
Mistake 3
Not understanding Event Loop.
Very common interview failure.
Mistake 4
Confusing Node.js with Express.js.
Express is a framework.
Node.js is the runtime.
Mistake 5
Ignoring real-world architecture questions.
Senior interviews focus on:
- Scalability
- Reliability
- Monitoring
- Security
not just syntax.
Mini Interview Challenge
Explain in your own words:
Question 1
Why is Node.js suitable for APIs?
Question 2
Why are streams useful?
Question 3
What happens when:
node app.jsis executed?
Question 4
How does Event Loop improve scalability?
Real Developer Advice
Many developers spend weeks memorizing interview answers.
Unfortunately:
Interviewers can easily detect memorization.
Instead:
Focus on understanding:
- Why Node.js exists
- How requests flow
- How Event Loop works
- How data moves through streams
- How backend systems scale
When you understand the concepts, answers become natural.
Real Backend Project Structure – How Professional Node.js Applications Are Organized
Introduction: Why Professional Projects Don't Have Everything Inside app.js
When developers first learn Node.js, their projects usually look like this:
project
│
└── app.jsInside:
// Login Logic
// Product Logic
// Orders Logic
// Payment Logic
// Email Logic
// Database Logic
// Validation Logic
// File Upload LogicAt first this feels manageable.
Then the project grows.
After a few weeks:
app.js
=
2,000 LinesA few months later:
app.js
=
10,000 LinesNow imagine AQAD running like this.
One employee handles:
- Vendor onboarding
- Retailer onboarding
- Orders
- Inventory
- Payments
- Logistics
- Analytics
Impossible.
Businesses grow by creating departments.
Software grows exactly the same way.
Professional backend applications divide responsibilities into folders and modules.
This chapter shows how real Node.js applications are structured in production environments.
The Goal of Project Structure
A good backend structure helps:
Scalability
Add new features easily.
Maintainability
Fix bugs faster.
Team Collaboration
Multiple developers work simultaneously.
Code Reusability
Avoid duplicate logic.
Clean Architecture
Easy to understand.
AQAD Backend Structure
A professional Node.js project might look like:
aqad-backend
│
├── src
│
├── config
│
├── routes
│
├── controllers
│
├── services
│
├── middlewares
│
├── models
│
├── validations
│
├── utils
│
├── uploads
│
├── logs
│
├── app.js
│
└── server.jsDon't worry.
We'll understand every folder.
Understanding Request Flow
Before discussing folders, let's understand what happens when a request arrives.
Example:
Retailer
↓
GET /products
↓
Route
↓
Middleware
↓
Controller
↓
Service
↓
Database
↓
ResponseThis flow exists in most professional backend systems.
Routes Folder
Think of routes as reception desks.
Real-Life Analogy
A customer enters AQAD headquarters.
Reception asks:
Which department do you need?
Routes perform the same job.
Example:
routes
│
├── userRoutes.js
├── productRoutes.js
├── orderRoutes.js
└── paymentRoutes.jsExample:
router.get(
'/products',
getProducts
);The route simply decides:
This request belongs to Product ControllerNothing more.
Controllers Folder
Controllers handle incoming requests.
Restaurant Analogy
Customer says:
I want a coffee.Waiter receives the request.
The waiter doesn't prepare the coffee.
The waiter forwards the request.
Controllers work similarly.
Example:
controllers
│
├── userController.js
├── productController.js
└── orderController.jsExample:
const getProducts =
async (req, res) => {
const products =
await productService
.getProducts();
res.json(products);
};Controller responsibilities:
- Receive request
- Validate input
- Call service
- Send response
Why Controllers Should Stay Small
Bad:
const getProducts =
async (req,res)=>{
// 500 lines
// Database
// Validation
// Business Logic
}Good:
const getProducts =
async (req,res)=>{
const products =
await productService
.getProducts();
res.json(products);
}Controllers should remain lightweight.
Services Folder
Services contain business logic.
This is where the real work happens.
AQAD Example
When retailer places order:
Business rules may include:
Check Inventory
Calculate Total
Apply Discounts
Calculate Tax
Generate Invoice
Create OrderThese belong inside services.
Example:
services
│
├── productService.js
├── orderService.js
└── paymentService.jsExample:
const createOrder =
async (data) => {
// Inventory Check
// Pricing Logic
// Order Creation
};Why Services Matter
Without services:
Controllers become massive.
With services:
Controller
↓
Service
↓
DatabaseClean separation.
Models Folder
Models represent database structures.
AQAD Example
Tables:
Users
Products
Orders
PaymentsEach table gets a model.
Example:
models
│
├── userModel.js
├── productModel.js
└── orderModel.jsModel responsibility:
Interact with database.
Example:
const getProductById =
async (id) => {
return productTable
.find(id);
};Validation Folder
Validation protects applications from bad data.
Example
Vendor creates product.
Bad request:
{
"price": -100
}Should not be accepted.
Validation checks:
Required Fields
Email Format
Phone Format
Password Rules
Price RulesFolder:
validations
│
├── userValidation.js
├── productValidation.js
└── orderValidation.jsExample:
const schema = {
title: required,
price: positive
};Middleware Folder
Middleware sits between:
Request
↓
ControllerThink of middleware as security guards.
Authentication Middleware
Example:
User Request
↓
JWT Verification
↓
Allow AccessExample:
const authMiddleware =
(req,res,next)=>{
// Verify Token
next();
}Logging Middleware
Every request gets recorded.
Example:
GET /products
POST /orders
PUT /usersUseful for monitoring.
Rate Limiting Middleware
Protects APIs.
Example:
100 Requests
Per MinutePrevent abuse.
Config Folder
Stores application configuration.
Example:
config
│
├── database.js
├── aws.js
└── environment.jsInstead of:
const region =
'me-central-1';hardcoded everywhere.
Use:
config.aws.regionEnvironment Variables
Never store secrets inside code.
Bad:
const secret =
'my-secret-key';Good:
process.env.JWT_SECRETExample:
PORT=5000
JWT_SECRET=secret
AWS_REGION=me-central-1Utils Folder
Utilities contain reusable helper functions.
Example:
utils
│
├── dateHelper.js
├── fileHelper.js
└── generateId.jsExample:
generateOrderId()used throughout project.
Uploads Folder
Stores uploaded files.
AQAD Example:
uploads
│
├── products
│
├── vendors
│
└── retailer-documentsContains:
- Images
- PDFs
- Trade licenses
- Documents
Logs Folder
Stores application logs.
Example:
logs
│
├── errors.log
├── orders.log
└── system.logUseful for troubleshooting.
app.js vs server.js
Many professional projects separate them.
app.js
Contains:
Routes
Middlewares
ConfigurationsExample:
const app =
express();
app.use(...);server.js
Starts server.
Example:
app.listen(
5000
);This separation improves testing.
Real AQAD Request Flow
Retailer requests:
GET /productsFlow:
Route
↓
Auth Middleware
↓
Controller
↓
Service
↓
Database
↓
ResponseLet's see this visually.
Route
router.get(
'/products',
getProducts
);Controller
const getProducts =
async(req,res)=>{
const data =
await productService
.getProducts();
res.json(data);
}Service
const getProducts =
async()=>{
return productModel
.getAll();
}Model
const getAll =
async()=>{
return db.products;
}Response:
[
{
"id":1,
"title":"Rice"
}
]Each layer has one responsibility.
Why This Architecture Scales
Imagine AQAD grows from:
1,000 Retailersto:
100,000 RetailersNew features become easier because:
- Routes stay organized
- Controllers stay clean
- Services contain logic
- Models manage data
The project remains maintainable.
Common Beginner Mistakes
Mistake 1
Putting Everything Inside Controller
Bad:
// Validation
// Database
// Business Logic
// Responseinside controller.
Mistake 2
Skipping Services
Many beginners directly call database from controller.
This becomes difficult to maintain.
Mistake 3
Hardcoding Secrets
Bad:
const jwtSecret =
'123456';Always use environment variables.
Mistake 4
Creating Huge Utility Files
Bad:
utils.jscontaining:
300 FunctionsSplit logically.
Mistake 5
Ignoring Logging
Production systems need logs.
Mini Exercise
Design folder structure for:
Library Management SystemCreate:
routes
controllers
services
models
middlewaresand decide responsibilities.
Try It Yourself
Create:
project
│
├── routes
├── controllers
├── services
├── models
│
├── app.js
└── server.jsBuild:
GET /productsflow using all layers.
This exercise helps understand architecture much better than memorizing theory.
Real Developer Insight
Junior developers often think:
"A good developer writes code."
Senior developers know:
"A good developer organizes code."
Most production issues are not caused by lack of coding ability.
They are caused by poor architecture.
A clean architecture allows:
- Faster development
- Easier debugging
- Better teamwork
- Easier scaling
This is why companies care so much about project structure.

0 Comments