Files
gh-cubical6-melly/skills/c4model-c2/common-container-patterns.md
2025-11-29 18:17:07 +08:00

525 lines
14 KiB
Markdown

# Common Container Patterns
This document provides reusable architecture patterns for C4 Model Level 2 (Container) analysis with detailed examples.
## Pattern 1: Simple SPA + API + Database
**Scenario:** Basic web application with frontend, backend, and database
**Containers identified:**
1. **Frontend SPA Container**
- Type: `spa`
- Technology: React 18 + TypeScript
- Runtime: Browser
- Communicates with API via HTTP REST
2. **Backend API Container**
- Type: `api`
- Technology: Express.js + Node.js 18
- Runtime: Server (Node.js)
- Communicates with database via PostgreSQL protocol
3. **PostgreSQL Database Container**
- Type: `database`
- Technology: PostgreSQL 15
- Runtime: Server (Docker)
- Stores application data
**Architecture:**
```
┌──────────────────┐
│ Browser │
│ ┌────────────┐ │
│ │ React SPA │ │
│ └──────┬─────┘ │
└─────────┼────────┘
│ HTTP REST
┌─────────────────┐
│ Server │
│ ┌────────────┐ │
│ │ Express API│ │
│ └──────┬─────┘ │
└─────────┼───────┘
│ SQL
┌─────────────────┐
│ ┌────────────┐ │
│ │PostgreSQL │ │
│ │ Database │ │
│ └────────────┘ │
└─────────────────┘
```
**Detection Commands:**
```bash
# Detect pattern
find . -name "package.json" | grep -E "(frontend|client|web)"
find . -name "package.json" | grep -E "(backend|server|api)"
find . -name "docker-compose.yml" | xargs grep postgres
# Verify frontend
cat frontend/package.json | jq '.dependencies | keys | .[]' | grep -E "react|vue|angular"
# Verify backend
cat backend/package.json | jq '.dependencies | keys | .[]' | grep -E "express|fastify|nestjs"
# Verify database
docker-compose config | grep postgres
```
---
## Pattern 2: Microservices with API Gateway
**Scenario:** Multiple microservices behind API gateway
**Containers identified:**
1. **API Gateway Container**
- Type: `web-server`
- Technology: Nginx or Kong
- Runtime: Server
- Routes requests to services
2. **Auth Service Container**
- Type: `api`
- Technology: NestJS
- Runtime: Server (Node.js in Docker)
- Handles authentication
3. **User Service Container**
- Type: `api`
- Technology: Spring Boot
- Runtime: Server (JVM in Docker)
- Manages user data
4. **Order Service Container**
- Type: `api`
- Technology: FastAPI
- Runtime: Server (Python in Docker)
- Processes orders
5. **Message Broker Container**
- Type: `message-broker`
- Technology: RabbitMQ
- Runtime: Server (Docker)
- Event bus
6. **Per-Service Databases**
- Each service has its own database container
**Architecture:**
```
┌──────────────┐
│ API Gateway │
└──────┬───────┘
│ HTTP
┌───┴────┬────────┐
│ │ │
▼ ▼ ▼
┌─────┐ ┌──────┐ ┌───────┐
│Auth │ │User │ │Order │
│Svc │ │Svc │ │Svc │
└──┬──┘ └──┬───┘ └───┬───┘
│ │ │
└───────┴────┬────┘
┌─────────┐
│RabbitMQ │
└─────────┘
```
**Detection Commands:**
```bash
# Detect microservices pattern
find . -type d -name "*-service" -o -name "*-api"
ls services/ | wc -l # Count service directories
# Find API gateway
grep -r "nginx\|kong\|traefik" docker-compose.yml k8s/
# Find message broker
grep -r "rabbitmq\|kafka" docker-compose.yml k8s/
# Count services
find services/ -name "package.json" -o -name "pom.xml" -o -name "requirements.txt" | wc -l
```
---
## Pattern 3: Serverless Architecture
**Scenario:** Serverless functions with managed services
**Containers identified:**
1. **Frontend SPA Container**
- Type: `spa`
- Deployed to: CloudFront + S3
- Technology: React
- Runtime: Browser
2. **API Lambda Functions Container(s)**
- Type: `api`
- Multiple functions or single function
- Technology: Node.js Lambda handlers
- Runtime: AWS Lambda (serverless)
3. **DynamoDB Database**
- Type: `database`
- Technology: AWS DynamoDB
- Runtime: AWS managed
- Fully serverless
4. **S3 Storage Container**
- Type: `file-storage`
- Technology: AWS S3
- Runtime: AWS managed
- Stores uploaded files
**Architecture:**
```
┌─────────────┐
│ CloudFront │
│ + S3 │
│ (SPA) │
└──────┬──────┘
│ HTTP
┌─────────────┐
│ API Gateway │
└──────┬──────┘
┌─────────────┐ ┌──────────┐
│ Lambda │──────▶ DynamoDB │
│ Functions │ └──────────┘
└─────────────┘
┌─────────────┐
│ S3 Bucket │
└─────────────┘
```
**Detection Commands:**
```bash
# Detect serverless pattern
find . -name "serverless.yml" -o -name "serverless.yaml"
find . -name "vercel.json" -o -name "netlify.toml"
find . -name "template.yaml" | xargs grep "AWS::Serverless"
# Find Lambda functions
grep -r "AWS::Serverless::Function\|handler:" serverless.yml
# Find DynamoDB tables
grep -r "DynamoDB\|AWS::DynamoDB" template.yaml
# Find S3 usage
grep -r "S3_BUCKET\|aws-sdk.*s3" .
```
---
## Pattern 4: Full-Stack Framework (Next.js/Nuxt)
**Scenario:** Single full-stack application with SSR
**Containers identified:**
1. **Next.js Application Container**
- Type: `app-server` (full-stack)
- Technology: Next.js 13
- Runtime: Server (Node.js)
- Serves both frontend and API routes
- **Note:** This is ONE container, not separate frontend/backend
2. **Database Container**
- Type: `database`
- Technology: PostgreSQL
- Runtime: Server (Docker)
3. **Redis Cache Container**
- Type: `cache`
- Technology: Redis
- Runtime: Server (Docker)
- Caches SSR pages
**Architecture:**
```
┌────────────────────┐
│ Next.js App │
│ ┌──────────────┐ │
│ │ SSR + API │ │
│ │ Routes │ │
│ └──────┬───────┘ │
└─────────┼──────────┘
┌─┴──┐
│ │
┌───▼──┐ └──▼─────┐
│ DB │ │ Redis │
└──────┘ └───────┘
```
**Detection Commands:**
```bash
# Detect Next.js/Nuxt pattern
grep -r "\"next\":\|\"nuxt\":" package.json
# Check for API routes
find . -type d -name "api" -path "*/pages/api" -o -path "*/app/api"
# Check for SSR
grep -r "getServerSideProps\|getStaticProps" pages/ app/
# Verify single application
[ $(find . -name "package.json" -not -path "*/node_modules/*" | wc -l) -eq 1 ] && echo "Single app"
```
---
## Pattern 5: Mobile App + Backend
**Scenario:** Mobile application with supporting backend
**Containers identified:**
1. **Mobile Application Container**
- Type: `mobile-app`
- Technology: React Native
- Runtime: iOS/Android
- Communicates with API
2. **Backend API Container**
- Type: `api`
- Technology: Django REST Framework
- Runtime: Server (Python)
- Provides mobile API
3. **PostgreSQL Database Container**
- Type: `database`
- Technology: PostgreSQL
- Runtime: Server
4. **Redis Cache Container**
- Type: `cache`
- Technology: Redis
- Runtime: Server
- API response caching
5. **Push Notification Service Container**
- Type: `worker`
- Technology: Custom Python service
- Runtime: Server
- Sends push notifications via FCM/APNS
**Architecture:**
```
┌─────────────────┐
│ Mobile Device │
│ ┌─────────────┐ │
│ │React Native │ │
│ │ App │ │
│ └──────┬──────┘ │
└────────┼────────┘
│ HTTPS
┌────────────────┐ ┌────────┐
│ Django API │──────▶ Postgres│
└────────┬───────┘ └────────┘
┌────┴────┐
▼ ▼
┌──────┐ ┌────────┐
│Redis │ │Push │
│Cache │ │Service │
└──────┘ └────────┘
```
**Detection Commands:**
```bash
# Detect mobile app
find . -name "package.json" | xargs grep "react-native\|@ionic\|flutter"
find . -name "Podfile" -o -name "build.gradle"
# Detect backend API
grep -r "djangorestframework\|flask\|fastapi" requirements.txt
# Find push notification service
grep -r "fcm\|apns\|firebase-admin" . | grep -v node_modules
```
---
## Pattern 6: Event-Driven with Workers
**Scenario:** Async processing with message queue and workers
**Containers identified:**
1. **Web Application Container**
- Type: `spa`
- Technology: Vue 3
- Runtime: Browser
2. **Backend API Container**
- Type: `api`
- Technology: FastAPI
- Runtime: Server (Python)
- Publishes events to queue
3. **Message Queue Container**
- Type: `message-broker`
- Technology: Kafka
- Runtime: Server (Docker)
- Event streaming
4. **Email Worker Container**
- Type: `worker`
- Technology: Celery
- Runtime: Server (Python)
- Consumes email events
5. **Report Worker Container**
- Type: `worker`
- Technology: Celery
- Runtime: Server (Python)
- Generates reports
6. **Database Container**
- Type: `database`
- Technology: PostgreSQL
- Runtime: Server
**Architecture:**
```
┌──────┐ ┌─────┐
│ Vue │───▶│ API │
│ SPA │ └──┬──┘
└──────┘ │
│ publish
┌──────────┐
│ Kafka │
│ Queue │
└─────┬────┘
┌───┴───┐
subscribe subscribe
│ │
┌────▼──┐ ┌─▼──────┐
│Email │ │Report │
│Worker │ │Worker │
└───────┘ └────────┘
```
**Detection Commands:**
```bash
# Detect event-driven pattern
grep -r "celery\|sidekiq\|bull\|bee-queue" requirements.txt package.json Gemfile
# Find message brokers
grep -r "kafka\|rabbitmq\|redis.*pub.*sub" docker-compose.yml
# Find worker definitions
find . -name "*worker*.py" -o -name "*job*.py"
grep -r "celery.*worker\|worker.*start" .
```
---
## Pattern Selection Guide
### When to Use Each Pattern
| Pattern | Best For | Complexity | Scalability |
|---------|----------|------------|-------------|
| Pattern 1: SPA + API + DB | Simple web apps, MVPs | Low | Medium |
| Pattern 2: Microservices | Large systems, independent teams | High | Very High |
| Pattern 3: Serverless | Variable load, cost optimization | Medium | Auto-scale |
| Pattern 4: Full-Stack Framework | Rapid development, SSR needs | Low-Medium | Medium |
| Pattern 5: Mobile + Backend | Mobile-first apps | Medium | High |
| Pattern 6: Event-Driven | Async processing, decoupling | Medium-High | Very High |
### Mixing Patterns
Real-world systems often combine patterns:
**Example: E-commerce Platform**
- Pattern 1: Customer web portal (SPA + API + DB)
- Pattern 5: Mobile shopping app (Mobile + Backend)
- Pattern 6: Order processing (Event-driven workers)
- Pattern 3: Static assets (Serverless CDN)
---
## Detection Best Practices
1. **Start with docker-compose.yml or K8s manifests** - Shows all containers
2. **Check package manifests** - package.json, requirements.txt, pom.xml
3. **Look for framework indicators** - next.config.js, serverless.yml
4. **Examine folder structure** - services/, apps/, packages/
5. **Review deployment configs** - Dockerfile, K8s deployments
6. **Check environment variables** - .env files reveal connections
## Common Variations
### Pattern 1 Variations
- Add Redis cache → Pattern 1 + Cache
- Add Nginx proxy → Pattern 1 + Reverse Proxy
- Add worker → Pattern 1 + Background Jobs
### Pattern 2 Variations
- Per-service databases → Database-per-Service
- Shared database → Shared-Database (anti-pattern)
- Service mesh → Add Istio/Linkerd sidecar containers
### Pattern 3 Variations
- Vercel deployment → Vercel Edge Functions
- Netlify deployment → Netlify Functions
- Azure → Azure Functions + Cosmos DB
### Pattern 4 Variations
- Monorepo → Multiple Next.js apps
- Standalone API → Next.js + Separate API
- Edge runtime → Vercel Edge Runtime
---
## Anti-Patterns to Avoid
1. **Shared Database Across Services**
- Violates microservices principles
- Creates tight coupling
- Makes each service dependent
2. **Monolith in Disguise**
- Multiple "microservices" that all call each other synchronously
- Should be one container
3. **Over-Granular Containers**
- Breaking down below deployment boundary
- Example: Separating utility functions into "containers"
4. **Missing Infrastructure Containers**
- Forgetting databases, caches, message brokers
- Only documenting application containers
5. **Generic Container Types**
- "Node.js App" instead of "Express API Server"
- "Python Service" instead of "FastAPI API + Celery Worker"
---
## Next Steps
After identifying the pattern:
1. **Document each container** using container-types-reference.md
2. **Map communication** using communication-patterns.md
3. **Capture technology details** using technology-detection-patterns.md
4. **Add observations** per observation-categories-c2.md
5. **Validate** using melly-validation scripts