Table of Contents
What is API?
API stands for Application Programming Interface. It is a rule-based bridge that allows two software applications to communicate with each other.
- Why used: data sharing, automation, integration, frontend-backend communication.
- Types: REST, SOAP, GraphQL, WebSocket, Library API, OS API, Payment API.
- Restaurant analogy: Customer = Client, Waiter = API, Kitchen = Server, Ingredients = Database.
When you open a weather app, the app sends a request to a weather API. The API talks to the server and database, then returns weather data as a response.
Simple REST API Request
GET /api/users HTTP/1.1
Host: example.com
Accept: application/json
Authorization: Bearer token
API Architecture
API architecture defines how client, server, database, proxy, authentication, and response format work together.
Client & Server
Client
Client is the software that sends request, like browser, mobile app, Postman, curl, or another backend service.
Server
Server receives request, processes business logic, talks to database, and sends response.
Backend
Backend is the server-side application code where APIs, authentication, validation, and business logic are written.
Database
Database stores persistent data like users, orders, products, sessions, and logs.
HTTP Methods
Request & Response
HTTP Request
Request contains method, URL, headers, and optional body.
POST /users HTTP/1.1
Content-Type: application/json
{"name":"Rohit"}
HTTP Response
Response contains status code, headers, and body.
HTTP/1.1 201 Created
Content-Type: application/json
{"id":1,"name":"Rohit"}
Headers
Request Headers
- Authorization: token/API key
- Content-Type: body format
- Accept: expected response format
- Host: server domain
- User-Agent: client details
Authorization: Bearer abc123
Content-Type: application/json
Accept: application/json
Host: api.example.com
User-Agent: Chrome
Response Headers
- Content-Type
- Cache-Control
- Access-Control-Allow-Origin
- Content-Length
Content-Type: application/json
Cache-Control: no-cache
Access-Control-Allow-Origin: *
Content-Length: 120
CORS
CORS means Cross-Origin Resource Sharing. Browser uses it as a security mechanism to control requests from one origin to another origin.
- Same Origin: same protocol, domain, and port.
- Cross Origin: different protocol, domain, or port.
- OPTIONS Preflight: browser checks server permission before actual request.
Express.js CORS Example
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') return res.sendStatus(204);
next();
});
Status Codes
Proxy, Forward Proxy & Reverse Proxy
Proxy is an intermediate server between client and destination server. It can be used for security, caching, filtering, privacy, load balancing, and traffic control.
Forward Proxy
Forward proxy sits in front of client. Server sees proxy instead of real client.
Advantages: privacy, filtering, access control. Disadvantages: latency, misconfiguration risk.
Example: company blocks social media using proxy.
Reverse Proxy
Reverse proxy sits in front of servers. Client talks to proxy; proxy forwards to backend servers.
- Load balancing
- SSL termination
- Caching
- Security
NGINX Reverse Proxy Example
server {
listen 80;
location / {
proxy_pass http://localhost:3000;
}
}
- server: defines virtual server block.
- listen 80: NGINX listens on HTTP port 80.
- location /: matches all root URL requests.
- proxy_pass: forwards traffic to backend app running on port 3000.
Complete API Flow Diagram
REST, Fetch API & Express.js Examples
REST API Example
GET /users // get all users
GET /users/1 // get one user
POST /users // create user
PUT /users/1 // update user
DELETE /users/1 // delete user
Fetch API Examples
// GET
fetch('/users').then(res => res.json()).then(console.log);
// POST
fetch('/users', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({name:'Rohit'})
});
// PUT
fetch('/users/1', { method:'PUT', headers:{'Content-Type':'application/json'}, body: JSON.stringify({name:'Updated'}) });
// DELETE
fetch('/users/1', { method:'DELETE' });
Complete Express.js API Example
const express = require('express');
const app = express();
app.use(express.json());
let users = [{ id: 1, name: 'Rohit' }];
// CORS + OPTIONS preflight
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') return res.status(204).send();
next();
});
// GET
app.get('/users', (req, res) => {
res.status(200).json({ success: true, data: users });
});
// POST
app.post('/users', (req, res) => {
const user = { id: Date.now(), name: req.body.name };
users.push(user);
res.status(201).json({ message: 'User created', data: user });
});
// PUT
app.put('/users/:id', (req, res) => {
const user = users.find(u => u.id == req.params.id);
if (!user) return res.status(404).json({ error: 'User not found' });
user.name = req.body.name;
res.status(200).json({ message: 'User updated', data: user });
});
// DELETE
app.delete('/users/:id', (req, res) => {
users = users.filter(u => u.id != req.params.id);
res.status(204).send();
});
app.listen(3000, () => console.log('API running on port 3000'));