--- id: wiki-2026-0508-client-server title: Client-Server Architecture Pattern category: 10_Wiki/Topics status: verified canonical_id: self aliases: [client-server, REST, gRPC, HTTP, web architecture, centralized model, two-tier, three-tier] duplicate_of: none source_trust_level: A confidence_score: 0.95 verification_status: applied tags: [architecture, client-server, rest, grpc, http, network, web-development, scalability] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: language-agnostic framework: HTTP / REST / gRPC / WebSocket --- # Client-Server Architecture ## ๐Ÿ“Œ ํ•œ ์ค„ ํ†ต์ฐฐ > **"๋งค ์ž์› ์˜ request โ†” provider"**. ๋งค dominant network model. ๋งค single point of failure ๊ฐ€, ๋งค scale + control ์˜ huge. ๋งค modern: ๋งค BFF, ๋งค edge, ๋งค multi-region, ๋งค P2P ์™€ ์˜ hybrid. ## ๋งค ํ•ต์‹ฌ ### ๋งค components - **Client**: ๋งค UI + ๋งค request. - **Server**: ๋งค logic + ๋งค data. - **Network protocol**: HTTP, gRPC, WebSocket, MQTT. ### ๋งค tier - **Two-tier**: client + DB. - **Three-tier**: client + app server + DB. - **N-tier**: client + BFF + microservices + DB + cache. ### ๋งค protocol comparison | Protocol | Use case | Latency | Streaming | |---|---|---|---| | REST/HTTP | General CRUD | mid | โœ— | | gRPC | Internal RPC | low | โœ“ (bidirectional) | | GraphQL | Flexible query | mid | partial (subscription) | | WebSocket | Real-time | very low | โœ“ | | Server-Sent Events | Server โ†’ Client | low | โœ“ (one-way) | | MQTT | IoT, low-bandwidth | low | โœ“ | | WebRTC | P2P media | very low | โœ“ | ### ๋งค advantages - ๋งค centralized control. - ๋งค division of labor. - ๋งค independent update. - ๋งค scale (server-side). - ๋งค strong security (server-side). ### ๋งค disadvantages - ๋งค single point of failure. - ๋งค network dependency. - ๋งค latency. - ๋งค cost (server infra). - ๋งค scaling complexity. ### ๋งค alternative / hybrid - **P2P** (BitTorrent, IPFS): ๋งค decentralized. - **Edge computing**: ๋งค close to user. - **Serverless**: ๋งค ephemeral. - **CRDT** + ๋งค sync: ๋งค offline-first. - **Local-first** (Ink & Switch). ### ๋งค modern pattern #### BFF (Backend for Frontend) - ๋งค mobile / web ๋ณ„ API. - ๋งค client-specific aggregation. #### API Gateway - ๋งค single entry. - ๋งค auth / rate / route. #### Service Mesh - ๋งค inter-service communication. - ๋งค Istio, Linkerd. #### CDN / Edge - ๋งค static content. - ๋งค closer to user. - ๋งค Cloudflare Workers, Vercel Edge. #### Multi-region - ๋งค active-active. - ๋งค latency ์˜ minimize. ## ๐Ÿ’ป ํŒจํ„ด ### REST API (Express) ```ts import express from 'express'; const app = express(); app.use(express.json()); app.get('/users/:id', async (req, res) => { const user = await db.users.findById(req.params.id); if (!user) return res.status(404).json({ error: 'Not found' }); res.json(user); }); app.post('/users', async (req, res) => { const user = await db.users.create(req.body); res.status(201).json(user); }); app.listen(3000); ``` ### gRPC (proto + server) ```protobuf // user.proto service UserService { rpc GetUser(GetUserRequest) returns (User); rpc StreamUsers(stream UserFilter) returns (stream User); } message GetUserRequest { string id = 1; } message User { string id = 1; string email = 2; } ``` ```ts import * as grpc from '@grpc/grpc-js'; const server = new grpc.Server(); server.addService(UserService, { getUser: async (call, callback) => { const user = await db.users.findById(call.request.id); callback(null, user); }, }); server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => server.start()); ``` ### WebSocket (real-time) ```ts import { WebSocketServer } from 'ws'; const wss = new WebSocketServer({ port: 8080 }); wss.on('connection', (ws) => { ws.on('message', (data) => { // ๋งค broadcast wss.clients.forEach(c => c.readyState === 1 && c.send(data)); }); }); ``` ### Server-Sent Events ```ts app.get('/events', (req, res) => { res.set({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', }); const interval = setInterval(() => { res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`); }, 1000); req.on('close', () => clearInterval(interval)); }); ``` ### Three-tier deployment ```yaml # docker-compose.yml services: client: image: my-frontend:latest ports: ['80:80'] api: image: my-api:latest environment: - DATABASE_URL=postgres://db:5432/app - REDIS_URL=redis://cache:6379 deploy: replicas: 3 cache: image: redis:7 db: image: postgres:16 volumes: ['./data:/var/lib/postgresql/data'] ``` ### API Gateway (Kong / Express middleware) ```ts // ๋งค simple gateway middleware import rateLimit from 'express-rate-limit'; import jwt from 'jsonwebtoken'; app.use(rateLimit({ windowMs: 60_000, max: 100 })); app.use((req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).end(); try { req.user = jwt.verify(token, process.env.JWT_SECRET!); next(); } catch { res.status(401).end(); } }); app.use('/api/users', proxy('http://user-service:3001')); app.use('/api/orders', proxy('http://order-service:3002')); ``` ### BFF (TypeScript) ```ts // ๋งค mobile-specific endpoint app.get('/mobile/dashboard', async (req, res) => { const [user, recent_orders, notifications] = await Promise.all([ userService.get(req.user.id), orderService.recent(req.user.id, 5), notificationService.unread(req.user.id), ]); // ๋งค mobile-friendly aggregate res.json({ user: { id: user.id, name: user.name }, recent: recent_orders.map(o => ({ id: o.id, total: o.total })), badge_count: notifications.length, }); }); ``` ### Edge Function (Cloudflare Workers) ```js export default { async fetch(request, env) { const url = new URL(request.url); // ๋งค edge cache const cache = caches.default; const cached = await cache.match(request); if (cached) return cached; // ๋งค origin fetch const response = await fetch(`https://origin.example.com${url.pathname}`); // ๋งค cache response.headers.set('Cache-Control', 'public, max-age=60'); await cache.put(request, response.clone()); return response; }, }; ``` ### Health check + circuit breaker ```ts app.get('/health', (req, res) => { const checks = { db: db.isConnected(), redis: redis.ping(), deps: externalApi.healthy(), }; if (Object.values(checks).every(v => v)) { res.json({ status: 'ok', checks }); } else { res.status(503).json({ status: 'degraded', checks }); } }); ``` ## ๐Ÿค” ๊ฒฐ์ • ๊ธฐ์ค€ | ์ƒํ™ฉ | Pattern | |---|---| | Web app | Three-tier + REST | | Internal services | gRPC + service mesh | | Real-time | WebSocket / SSE | | IoT | MQTT | | Mobile | REST + BFF | | Offline-first | CRDT sync + local-first | | Cross-region read | Edge + CDN | | P2P file | BitTorrent / IPFS | | Heavy media | WebRTC | **๊ธฐ๋ณธ๊ฐ’**: REST + 3-tier. ๋งค internal = gRPC. ๋งค real-time = WebSocket. ## ๐Ÿ”— Graph - ๋ถ€๋ชจ: [[Software Architecture Styles]] ยท [[Distributed-Systems]] - ๋ณ€ํ˜•: [[REST]] ยท [[gRPC]] ยท [[MQTT]] ยท [[WebRTC]] - ์‘์šฉ: [[BFF]] ยท [[API-Gateway]] ยท [[Service Mesh]] ยท [[Edge Computing|Edge-Computing]] - ๋Œ€์•ˆ: [[Local-First]] ยท [[Serverless]] ยท [[CRDT]] - Adjacent: [[CAP-Theorem]] ยท [[Availability-and-Persistence]] ยท [[Microservices]] ## ๐Ÿค– LLM ํ™œ์šฉ **์–ธ์ œ**: ๋งค system design. ๋งค protocol decision. ๋งค architecture review. ๋งค onboarding. **์–ธ์ œ X**: ๋งค single-machine app. ๋งค P2P-only domain. ## โŒ ์•ˆํ‹ฐํŒจํ„ด - **Single-point-of-failure ๋ฌด์‹œ**: ๋งค multi-AZ ์˜ X. - **Chatty client (N+1)**: ๋งค BFF ์˜ lieu. - **Synchronous chain (5+ hop)**: ๋งค cascading failure. - **No rate limit**: ๋งค abuse vulnerability. - **REST on real-time**: ๋งค polling overhead. - **gRPC for browser**: ๋งค ๋งค gateway ํ•„์š”. - **No health check**: ๋งค silent degradation. ## ๐Ÿงช ๊ฒ€์ฆ / ์ค‘๋ณต - Verified (Roy Fielding REST thesis, gRPC docs, BFF pattern Sam Newman). - ์‹ ๋ขฐ๋„ A. - Related: [[Software Architecture Styles]] ยท [[Microservices]] ยท [[CAP-Theorem]] ยท [[Bounded Contexts (DDD)]] ยท [[Availability-and-Persistence]]. ## ๐Ÿ•“ Changelog | ๋‚ ์งœ | ๋ณ€๊ฒฝ | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup โ€” protocol matrix + tier + modern patterns + ๋งค Express / gRPC / WS / Edge code |