Backend Developer Guide

Comprehensive technical reference with practical examples and implementation guides

HTTP Methods & Status Codes

HTTP Methods

MethodPurposeIdempotentExample Use
GETRetrieve resource✓Get user list
POSTCreate resource✗Create new user
PUTReplace resource✓Update full user
PATCHPartial update✗Update user email
DELETERemove resource✓Delete user
Express.js API
// RESTful API Implementation
router.get('/users', async (req, res) => {
    const users = await User.find();
    res.json(users);
});

router.post('/users', async (req, res) => {
    const user = await User.create(req.body);
    res.status(201).location(\`/users/\${user.id}\`).json(user);
});

router.patch('/users/:id', async (req, res) => {
    const user = await User.findByIdAndUpdate(req.params.id, { $set: req.body }, { new: true });
    if (!user) return res.status(404).json({ error: 'Not found' });
    res.json(user);
});

HTTP Status Codes

CodeMeaningWhen to Use
200OKSuccessful GET, PUT, PATCH
201CreatedSuccessful POST with new resource
204No ContentSuccessful DELETE
400Bad RequestInvalid request body/params
401UnauthorizedMissing/invalid authentication
403ForbiddenAuthenticated but no permission
404Not FoundResource doesn't exist
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Authentication: OAuth, OIDC, JWT & Sessions

OAuth 2.0 vs OpenID Connect

AspectOAuth 2.0OpenID Connect (OIDC)
PurposeAuthorization (access)Authentication (identity)
TokenAccess TokenID Token (JWT) + Access Token
User InfoNoYes (profile, email, etc)
Use CaseAPI access delegationSingle Sign-On (SSO)

JWT vs Sessions

JWT (Stateless)

  • Self-contained tokens
  • No server storage
  • Scales easily horizontally
  • Can't revoke before expiry
  • Larger payload

Sessions (Stateful)

  • Session ID in cookie
  • Requires Redis/DB storage
  • Needs sticky sessions
  • Instant revocation
  • Smaller cookie
JWT Implementation
const jwt = require('jsonwebtoken');

// Generate JWT
function generateToken(userId) {
    return jwt.sign(
        { userId, type: 'access' },
        process.env.JWT_SECRET,
        { expiresIn: '15m' }
    );
}

// Verify middleware
function auth(req, res, next) {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) return res.status(401).json({ error: 'No token' });
    
    try {
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        req.userId = decoded.userId;
        next();
    } catch (err) {
        res.status(401).json({ error: 'Invalid token' });
    }
}

Security: Hashing, Encryption & Rate Limiting

Password Hashing with Bcrypt

Node.js
const bcrypt = require('bcrypt');
const SALT_ROUNDS = 12;

// Hash password
async function hashPassword(password) {
    return await bcrypt.hash(password, SALT_ROUNDS);
}

// Verify password
async function verifyPassword(password, hash) {
    return await bcrypt.compare(password, hash);
}

// Registration
router.post('/register', async (req, res) => {
    const hashedPassword = await hashPassword(req.body.password);
    const user = await User.create({ ...req.body, password: hashedPassword });
    res.status(201).json({ id: user.id });
});

Encryption Standards

AES-256 Encryption
const crypto = require('crypto');

// Encrypt data
function encrypt(text, key) {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv('aes-256-gcm', Buffer.from(key, 'hex'), iv);
    const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);
    const authTag = cipher.getAuthTag();
    return { iv: iv.toString('hex'), data: encrypted.toString('hex'), authTag: authTag.toString('hex') };
}

// Decrypt data
function decrypt(encrypted, key) {
    const decipher = crypto.createDecipheriv('aes-256-gcm', Buffer.from(key, 'hex'), Buffer.from(encrypted.iv, 'hex'));
    decipher.setAuthTag(Buffer.from(encrypted.authTag, 'hex'));
    const decrypted = Buffer.concat([decipher.update(Buffer.from(encrypted.data, 'hex')), decipher.final()]);
    return decrypted.toString('utf8');
}

Rate Limiting & DDoS Protection

Express Rate Limit
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const redis = require('redis');

const limiter = rateLimit({
    store: new RedisStore({ client: redis.createClient() }),
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // limit each IP to 100 requests per windowMs
    message: 'Too many requests, please try again later',
    standardHeaders: true,
    legacyHeaders: false,
});

app.use('/api/', limiter);

WebSockets & Real-time Communication

WebSockets provide full-duplex communication channels over a single TCP connection, enabling real-time data transfer.

Socket.io Server
const io = require('socket.io')(server, {
    cors: { origin: '*' }
});

io.on('connection', (socket) => {
    console.log('Client connected:', socket.id);
    
    // Join room
    socket.on('join', (room) => {
        socket.join(room);
        socket.to(room).emit('user-joined', socket.id);
    });
    
    // Broadcast message
    socket.on('message', (data) => {
        io.to(data.room).emit('message', {
            user: socket.id,
            text: data.text,
            timestamp: Date.now()
        });
    });
    
    socket.on('disconnect', () => {
        console.log('Client disconnected');
    });
});
Client Implementation
const socket = io('http://localhost:3000');

socket.on('connect', () => {
    console.log('Connected to server');
    socket.emit('join', 'room1');
});

socket.on('message', (data) => {
    console.log('New message:', data);
});

function sendMessage(text) {
    socket.emit('message', { room: 'room1', text });
}

Databases: SQL, NoSQL, ACID & Optimization

SQL vs NoSQL

FeatureSQL (PostgreSQL, MySQL)NoSQL (MongoDB, Cassandra)
SchemaFixed schema, tablesFlexible schema, documents
ScalabilityVertical (scale up)Horizontal (scale out)
ACIDFull ACID complianceEventually consistent
JoinsComplex joins supportedNo joins (denormalized)
Use CaseStructured data, transactionsFlexible data, high throughput

ACID Properties

PostgreSQL Transaction
-- Bank transfer example
BEGIN;

UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;

-- Only commits if both succeed
COMMIT;

Indexing Strategies

Index Types
-- B-Tree index (default, good for =, <, >, <=, >=)
CREATE INDEX idx_users_email ON users(email);

-- Unique index
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);

-- Composite index
CREATE INDEX idx_users_name_age ON users(last_name, first_name, age);

-- Partial index
CREATE INDEX idx_active_users ON users(email) WHERE status = 'active';

-- Full-text search
CREATE INDEX idx_posts_content ON posts USING gin(to_tsvector('english', content));

Query Optimization

Optimization Techniques
-- Use EXPLAIN to analyze query
EXPLAIN ANALYZE
SELECT u.name, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at > '2024-01-01'
GROUP BY u.id, u.name
HAVING COUNT(o.id) > 5;

-- Optimize with proper indexes
CREATE INDEX idx_users_created ON users(created_at);
CREATE INDEX idx_orders_user ON orders(user_id);

-- Avoid SELECT *, specify columns
SELECT id, name, email FROM users;

-- Use LIMIT for pagination
SELECT * FROM users ORDER BY created_at DESC LIMIT 10 OFFSET 20;

Normalization vs Denormalization

AspectNormalizationDenormalization
RedundancyMinimalIntentional duplication
WritesFast (single location)Slower (multiple updates)
ReadsSlower (requires joins)Faster (pre-joined)
StorageEfficientMore space needed
Use WhenWrite-heavy, consistency criticalRead-heavy, performance critical

System Design & Architecture

Monolith vs Microservices

AspectMonolithMicroservices
StructureSingle deployable unitMultiple independent services
DeploymentDeploy entire appDeploy services independently
ScalabilityScale entire appScale services individually
ComplexitySimpler initiallyComplex infrastructure
TechnologySingle stackPolyglot (different tech per service)
Best ForSmall teams, MVPsLarge teams, complex systems

Load Balancing

Nginx Load Balancer
http {
    upstream backend {
        least_conn;  # Load balancing algorithm
        server backend1.example.com:3000 weight=3;
        server backend2.example.com:3000 weight=2;
        server backend3.example.com:3000 backup;
    }

    server {
        listen 80;
        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

Caching Strategies

Redis Caching
const redis = require('redis');
const client = redis.createClient();

// Cache-aside pattern
async function getUser(id) {
    // Try cache first
    const cached = await client.get(\`user:\${id}\`);
    if (cached) return JSON.parse(cached);
    
    // Cache miss: fetch from DB
    const user = await User.findById(id);
    
    // Store in cache
    await client.setex(\`user:\${id}\`, 3600, JSON.stringify(user));
    
    return user;
}

// Cache invalidation
async function updateUser(id, data) {
    const user = await User.findByIdAndUpdate(id, data);
    await client.del(\`user:\${id}\`);  // Invalidate cache
    return user;
}

Message Brokers: Kafka vs RabbitMQ

FeatureKafkaRabbitMQ
ModelPub/Sub, Log-basedQueue-based, Routing
ThroughputVery high (millions/sec)High (tens of thousands/sec)
OrderingGuaranteed per partitionPer queue
RetentionConfigurable (days/weeks)Transient (consumed once)
Use CaseEvent streaming, logsTask queues, RPC

DevOps: Docker, CI/CD, Linux

Docker Containerization

Dockerfile
# Multi-stage build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
USER node
CMD ["node", "server.js"]
docker-compose.yml
version: '3.8'
services:
  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=postgres
    depends_on:
      - postgres
      - redis
  
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data
  
  redis:
    image: redis:7-alpine
    
volumes:
  pgdata:

CI/CD Pipeline

GitHub Actions
name: CI/CD Pipeline
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm ci
      - run: npm test
      - run: npm run lint
  
  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build Docker image
        run: docker build -t myapp:latest .
      - name: Push to registry
        run: |
          echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
          docker push myapp:latest
      - name: Deploy to production
        run: kubectl apply -f k8s/

Linux Command Line Essentials

Bash
# Process management
ps aux | grep node
kill -9 
top / htop

# Logs
tail -f /var/log/app.log
grep "ERROR" app.log | wc -l
journalctl -u myservice -f

# Networking
netstat -tulpn
curl -X POST http://api.example.com/users -d '{"name":"John"}'
wget https://example.com/file.zip

# File operations
find /var/log -name "*.log" -mtime +7 -delete
du -sh /var/lib/docker
tar -czf backup.tar.gz /data/

# Permissions
chmod 755 script.sh
chown www-data:www-data /var/www/html

# Bash scripting
#!/bin/bash
for i in {1..5}; do
    echo "Iteration $i"
    curl http://localhost:3000/health
    sleep 5
done

Cloud Services (AWS/GCP/Azure)

Service TypeAWSGCPAzure
ComputeEC2, LambdaCompute Engine, Cloud FunctionsVM, Functions
StorageS3, EBSCloud Storage, Persistent DiskBlob Storage
DatabaseRDS, DynamoDBCloud SQL, FirestoreSQL Database, Cosmos DB
ContainersECS, EKSGKEAKS
CDNCloudFrontCloud CDNAzure CDN

Scalability & Performance

Vertical vs Horizontal Scaling

AspectVertical (Scale Up)Horizontal (Scale Out)
MethodIncrease server resourcesAdd more servers
LimitHardware maximumNearly unlimited
CostExpensive at scaleCost-effective
DowntimeRequired for upgradesZero downtime
ComplexitySimpleRequires load balancing

Database Sharding

Sharding Strategy
// Hash-based sharding
function getShardId(userId, numShards) {
    const hash = crypto.createHash('md5').update(userId.toString()).digest('hex');
    return parseInt(hash, 16) % numShards;
}

// Route to correct shard
function getUserDatabase(userId) {
    const shardId = getShardId(userId, 4);
    return databases[shardId];
}

// Example usage
const user = await getUserDatabase(userId).findOne({ id: userId });

Database Replication

Master-Replica Setup
// Configure read/write splitting
const masterDb = new Sequelize('postgres://master:5432/db');
const replicaDb = new Sequelize('postgres://replica:5432/db');

// Write to master
async function createUser(data) {
    return await masterDb.models.User.create(data);
}

// Read from replica
async function getUsers() {
    return await replicaDb.models.User.findAll();
}

Connection Pooling

PostgreSQL Pool
const { Pool } = require('pg');

const pool = new Pool({
    host: 'localhost',
    port: 5432,
    database: 'mydb',
    user: 'postgres',
    password: 'secret',
    max: 20,              // Max connections
    idleTimeoutMillis: 30000,
    connectionTimeoutMillis: 2000,
});

// Use pool for queries
async function query(sql, params) {
    const client = await pool.connect();
    try {
        const result = await client.query(sql, params);
        return result.rows;
    } finally {
        client.release();
    }
}

Testing, Logging & Monitoring

Testing Pyramid

Unit Tests (Jest)
describe('UserService', () => {
    test('should create user with hashed password', async () => {
        const userData = { email: 'test@example.com', password: 'secret123' };
        const user = await UserService.create(userData);
        
        expect(user.email).toBe(userData.email);
        expect(user.password).not.toBe(userData.password);
        expect(await bcrypt.compare(userData.password, user.password)).toBe(true);
    });
});
Integration Tests
const request = require('supertest');
const app = require('../app');

describe('POST /api/users', () => {
    test('should create user and return 201', async () => {
        const res = await request(app)
            .post('/api/users')
            .send({ email: 'test@example.com', password: 'secret123' });
        
        expect(res.status).toBe(201);
        expect(res.body).toHaveProperty('id');
        expect(res.body.email).toBe('test@example.com');
    });
});
Load Testing (k6)
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
    vus: 100,        // 100 virtual users
    duration: '30s',  // Test duration
};

export default function() {
    const res = http.get('http://api.example.com/users');
    check(res, {
        'status is 200': (r) => r.status === 200,
        'response time < 200ms': (r) => r.timings.duration < 200,
    });
    sleep(1);
}

Structured Logging

Winston Logger
const winston = require('winston');

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.errors({ stack: true }),
        winston.format.json()
    ),
    transports: [
        new winston.transports.File({ filename: 'error.log', level: 'error' }),
        new winston.transports.File({ filename: 'combined.log' }),
    ],
});

// Usage
logger.info('User created', { userId: 123, email: 'user@example.com' });
logger.error('Database connection failed', { error: err.message, stack: err.stack });

Monitoring with Prometheus

Prometheus Metrics
const client = require('prom-client');

// Create metrics
const httpRequestDuration = new client.Histogram({
    name: 'http_request_duration_seconds',
    help: 'Duration of HTTP requests in seconds',
    labelNames: ['method', 'route', 'status_code']
});

const activeConnections = new client.Gauge({
    name: 'active_connections',
    help: 'Number of active connections'
});

// Middleware
app.use((req, res, next) => {
    const start = Date.now();
    res.on('finish', () => {
        const duration = (Date.now() - start) / 1000;
        httpRequestDuration.labels(req.method, req.route.path, res.statusCode).observe(duration);
    });
    next();
});

// Metrics endpoint
app.get('/metrics', async (req, res) => {
    res.set('Content-Type', client.register.contentType);
    res.end(await client.register.metrics());
});

Distributed Tracing

OpenTelemetry
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');

const provider = new NodeTracerProvider();
const exporter = new JaegerExporter({ endpoint: 'http://localhost:14268/api/traces' });

provider.addSpanProcessor(new BatchSpanProcessor(exporter));
provider.register();

// Create spans
const tracer = provider.getTracer('my-service');
const span = tracer.startSpan('database-query');
// ... do work
span.end();

✨ Complete Backend Developer Reference - Updated 2026

For questions or contributions: GitHub