Skip to main content
Glama
backend-architecture-2025.md6.55 kB
# Backend Architecture 2025 **Updated**: 2025-11-23 | **Stack**: Node.js, FastAPI, Go, Microservices --- ## API Design (REST + GraphQL) ### RESTful Best Practices ``` GET /api/users - List users GET /api/users/:id - Get user POST /api/users - Create user PUT /api/users/:id - Update user (full) PATCH /api/users/:id - Update user (partial) DELETE /api/users/:id - Delete user Response: 200 OK, 201 Created, 204 No Content 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found 500 Internal Server Error ``` ### Express.js API ```typescript import express from 'express'; import { z } from 'zod'; const app = express(); app.use(express.json()); const userSchema = z.object({ name: z.string().min(3), email: z.string().email(), age: z.number().int().positive().optional() }); app.post('/api/users', async (req, res) => { try { const data = userSchema.parse(req.body); const user = await db.user.create({ data }); res.status(201).json(user); } catch (error) { if (error instanceof z.ZodError) { res.status(400).json({ errors: error.errors }); } else { res.status(500).json({ error: 'Internal server error' }); } } }); ``` ### FastAPI (Python) ```python from fastapi import FastAPI, HTTPException from pydantic import BaseModel, EmailStr app = FastAPI() class UserCreate(BaseModel): name: str email: EmailStr age: int | None = None @app.post("/api/users", status_code=201) async def create_user(user: UserCreate): # Validation automatic via Pydantic db_user = await db.users.create(**user.model_dump()) return db_user @app.get("/api/users/{user_id}") async def get_user(user_id: int): user = await db.users.get(user_id) if not user: raise HTTPException(status_code=404, detail="User not found") return user ``` --- ## Database Patterns ### Repository Pattern ```typescript // repositories/UserRepository.ts export class UserRepository { async findById(id: number): Promise<User | null> { return prisma.user.findUnique({ where: { id } }); } async create(data: CreateUserDto): Promise<User> { return prisma.user.create({ data }); } async update(id: number, data: UpdateUserDto): Promise<User> { return prisma.user.update({ where: { id }, data }); } } // services/UserService.ts export class UserService { constructor(private userRepo: UserRepository) {} async getUser(id: number): Promise<User> { const user = await this.userRepo.findById(id); if (!user) throw new NotFoundError('User not found'); return user; } } ``` ### Transactions ```typescript // Prisma await prisma.$transaction(async (tx) => { const user = await tx.user.create({ data: userData }); await tx.profile.create({ data: { userId: user.id, ...profileData } }); }); // TypeORM await dataSource.transaction(async (manager) => { const user = await manager.save(User, userData); await manager.save(Profile, { userId: user.id, ...profileData }); }); ``` --- ## Microservices Architecture ``` API Gateway (Kong, nginx) ↓ ┌───────────┬───────────┬───────────┐ │ Auth │ Users │ Orders │ │ Service │ Service │ Service │ └─────┬─────┴─────┬─────┴─────┬─────┘ ↓ ↓ ↓ Redis PostgreSQL MongoDB ``` ### Service Communication ```typescript // gRPC (Proto definition) service UserService { rpc GetUser (UserRequest) returns (UserResponse); rpc CreateUser (CreateUserRequest) returns (UserResponse); } // Message Queue (RabbitMQ) await channel.sendToQueue('user.created', Buffer.from(JSON.stringify({ userId: user.id, email: user.email }))); // Event-driven (EventEmitter) eventEmitter.on('user.created', async (user) => { await sendWelcomeEmail(user.email); await analytics.track('user_signup', { userId: user.id }); }); ``` --- ## Caching Strategies ```typescript // Redis caching async function getUser(id: number): Promise<User> { const cacheKey = `user:${id}`; // Try cache first const cached = await redis.get(cacheKey); if (cached) return JSON.parse(cached); // Cache miss - fetch from DB const user = await db.user.findUnique({ where: { id } }); // Store in cache (1 hour TTL) await redis.setex(cacheKey, 3600, JSON.stringify(user)); return user; } // Cache invalidation async function updateUser(id: number, data: UpdateUserDto): Promise<User> { const user = await db.user.update({ where: { id }, data }); await redis.del(`user:${id}`); // Invalidate cache return user; } ``` --- ## Authentication & Authorization ### JWT ```typescript import jwt from 'jsonwebtoken'; // Generate token function generateToken(userId: number): string { return jwt.sign( { userId }, process.env.JWT_SECRET!, { expiresIn: '7d' } ); } // Middleware function authenticate(req, res, next) { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ error: 'Unauthorized' }); try { const decoded = jwt.verify(token, process.env.JWT_SECRET!); req.userId = decoded.userId; next(); } catch { res.status(401).json({ error: 'Invalid token' }); } } ``` --- ## Rate Limiting ```typescript import rateLimit from 'express-rate-limit'; const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // Max 100 requests per window message: 'Too many requests' }); app.use('/api/', limiter); ``` --- ## Error Handling ```typescript class AppError extends Error { constructor( public statusCode: number, public message: string ) { super(message); } } // Global error handler app.use((err, req, res, next) => { if (err instanceof AppError) { res.status(err.statusCode).json({ error: err.message }); } else { console.error(err); res.status(500).json({ error: 'Internal server error' }); } }); ``` --- ## Key Takeaways 1. **API Design**: REST for CRUD, GraphQL for complex queries 2. **Database**: Use ORMs, implement transactions 3. **Caching**: Redis for performance 4. **Security**: JWT, rate limiting, input validation 5. **Monitoring**: Logs, metrics, alerts --- ## References - Node.js Best Practices - FastAPI Documentation - "Designing Data-Intensive Applications" **Related**: `api-security.md`, `database-optimization.md`, `microservices.md`

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/seanshin0214/persona-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server