@wipal/agent-team 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/rules/common/general-rules.md +141 -0
- package/.claude/rules/lessons/lessons.md +91 -0
- package/.claude/rules/role-rules/dev-fe-rules.md +146 -0
- package/.claude/rules/role-rules/sa-rules.md +226 -0
- package/.claude/skills/SKILL-INDEX.md +299 -0
- package/.claude/skills/community/security-validator/SKILL.md +392 -0
- package/.claude/skills/core/agent-creation/SKILL.md +338 -0
- package/.claude/skills/core/code-review/SKILL.md +154 -0
- package/.claude/skills/core/git-automation/SKILL.md +93 -0
- package/.claude/skills/core/retrospect-work/SKILL.md +172 -0
- package/.claude/skills/domain/architecture/adr-writing/SKILL.md +254 -0
- package/.claude/skills/domain/architecture/adr-writing/references/adr-best-practices.md +257 -0
- package/.claude/skills/domain/architecture/adr-writing/references/adr-examples.md +246 -0
- package/.claude/skills/domain/architecture/adr-writing/references/adr-template.md +160 -0
- package/.claude/skills/domain/architecture/architecture-patterns/SKILL.md +316 -0
- package/.claude/skills/domain/architecture/architecture-patterns/references/event-driven.md +393 -0
- package/.claude/skills/domain/architecture/architecture-patterns/references/microservices.md +315 -0
- package/.claude/skills/domain/architecture/architecture-patterns/references/monolith.md +321 -0
- package/.claude/skills/domain/architecture/architecture-patterns/references/serverless.md +457 -0
- package/.claude/skills/domain/architecture/performance-engineering/SKILL.md +227 -0
- package/.claude/skills/domain/architecture/performance-engineering/references/benchmarking.md +336 -0
- package/.claude/skills/domain/architecture/performance-engineering/references/caching-strategies.md +284 -0
- package/.claude/skills/domain/architecture/performance-engineering/references/optimization.md +298 -0
- package/.claude/skills/domain/architecture/security-architecture/SKILL.md +206 -0
- package/.claude/skills/domain/architecture/security-architecture/references/auth-patterns.md +209 -0
- package/.claude/skills/domain/architecture/security-architecture/references/compliance.md +246 -0
- package/.claude/skills/domain/architecture/security-architecture/references/threat-modeling.md +219 -0
- package/.claude/skills/domain/architecture/system-design/SKILL.md +227 -0
- package/.claude/skills/domain/architecture/system-design/references/distributed-systems.md +231 -0
- package/.claude/skills/domain/architecture/system-design/references/resilience.md +344 -0
- package/.claude/skills/domain/architecture/system-design/references/scalability.md +303 -0
- package/.claude/skills/domain/architecture/tech-selection/SKILL.md +192 -0
- package/.claude/skills/domain/architecture/tech-selection/references/build-vs-buy.md +258 -0
- package/.claude/skills/domain/architecture/tech-selection/references/evaluation-framework.md +203 -0
- package/.claude/skills/domain/architecture/tech-selection/references/tech-radar.md +257 -0
- package/.claude/skills/domain/backend/api-design/SKILL.md +121 -0
- package/.claude/skills/domain/backend/database-design/SKILL.md +156 -0
- package/.claude/skills/domain/backend/performance-be/SKILL.md +210 -0
- package/.claude/skills/domain/backend/security/SKILL.md +138 -0
- package/.claude/skills/domain/backend/testing-be/SKILL.md +203 -0
- package/.claude/skills/domain/devops/ci-cd/SKILL.md +188 -0
- package/.claude/skills/domain/devops/containerization/SKILL.md +177 -0
- package/.claude/skills/domain/devops/deployment/SKILL.md +198 -0
- package/.claude/skills/domain/devops/infrastructure-as-code/SKILL.md +178 -0
- package/.claude/skills/domain/devops/monitoring/SKILL.md +163 -0
- package/.claude/skills/domain/frontend/accessibility/SKILL.md +179 -0
- package/.claude/skills/domain/frontend/frontend-design/SKILL.md +138 -0
- package/.claude/skills/domain/frontend/performance-fe/SKILL.md +195 -0
- package/.claude/skills/domain/frontend/state-management/SKILL.md +190 -0
- package/.claude/skills/domain/frontend/testing-fe/SKILL.md +193 -0
- package/.claude/skills/domain/product/requirements-gathering/SKILL.md +136 -0
- package/.claude/skills/domain/product/roadmap-planning/SKILL.md +169 -0
- package/.claude/skills/domain/product/sprint-planning/SKILL.md +151 -0
- package/.claude/skills/domain/product/stakeholder-communication/SKILL.md +162 -0
- package/.claude/skills/domain/product/user-stories/SKILL.md +141 -0
- package/.claude/skills/domain/quality/bug-reporting/SKILL.md +150 -0
- package/.claude/skills/domain/quality/regression-testing/SKILL.md +178 -0
- package/.claude/skills/domain/quality/test-automation/SKILL.md +185 -0
- package/.claude/skills/domain/quality/test-planning/SKILL.md +177 -0
- package/.claude/skills/leadership/code-review-advanced/SKILL.md +167 -0
- package/.claude/skills/leadership/mentoring/SKILL.md +151 -0
- package/.claude/skills/leadership/technical-debt/SKILL.md +166 -0
- package/.claude/skills/leadership/technical-decision/SKILL.md +160 -0
- package/.claude/skills/security-reports/.gitkeep +0 -0
- package/.claude/skills/skills-registry.yaml +441 -0
- package/README.md +232 -0
- package/bin/agent-team.js +107 -0
- package/package.json +51 -0
- package/src/commands/add.js +227 -0
- package/src/commands/init.js +136 -0
- package/src/commands/list.js +66 -0
- package/src/commands/remove.js +71 -0
- package/src/commands/switch.js +53 -0
- package/src/index.js +11 -0
- package/src/interactive/prompts.js +153 -0
- package/src/server/api/agents.js +150 -0
- package/src/server/api/roles.js +97 -0
- package/src/server/api/skills.js +79 -0
- package/src/server/index.js +78 -0
- package/src/ui/agents.html +174 -0
- package/src/ui/css/styles.css +470 -0
- package/src/ui/index.html +107 -0
- package/src/ui/roles.html +371 -0
- package/src/ui/skills.html +332 -0
- package/src/utils/file-utils.js +193 -0
- package/src/utils/skill-resolver.js +594 -0
- package/src/utils/skill-scanner.js +154 -0
- package/templates/CLAUDE.md.tmpl +42 -0
- package/templates/knowledge.md.tmpl +31 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# Event-Driven Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Event-Driven Architecture (EDA) is a software design pattern in which decoupled services communicate via events - state changes that services publish and consume asynchronously.
|
|
5
|
+
|
|
6
|
+
## Core Concepts
|
|
7
|
+
|
|
8
|
+
### What is an Event?
|
|
9
|
+
```
|
|
10
|
+
An event is a record of something that happened:
|
|
11
|
+
- Immutable fact
|
|
12
|
+
- Past tense (OrderPlaced, not PlaceOrder)
|
|
13
|
+
- Contains relevant data
|
|
14
|
+
- Timestamped
|
|
15
|
+
|
|
16
|
+
Example Event:
|
|
17
|
+
{
|
|
18
|
+
"type": "OrderPlaced",
|
|
19
|
+
"timestamp": "2024-01-15T10:30:00Z",
|
|
20
|
+
"data": {
|
|
21
|
+
"orderId": "12345",
|
|
22
|
+
"customerId": "67890",
|
|
23
|
+
"items": [...],
|
|
24
|
+
"total": 99.99
|
|
25
|
+
},
|
|
26
|
+
"metadata": {
|
|
27
|
+
"source": "order-service",
|
|
28
|
+
"version": "1.0",
|
|
29
|
+
"correlationId": "abc-123"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Event vs Command vs Query
|
|
35
|
+
```
|
|
36
|
+
Command (Imperative):
|
|
37
|
+
- "PlaceOrder" - Tells system to do something
|
|
38
|
+
- Expect specific handler
|
|
39
|
+
- Can be rejected
|
|
40
|
+
- Synchronous usually
|
|
41
|
+
|
|
42
|
+
Event (Declarative):
|
|
43
|
+
- "OrderPlaced" - Announces something happened
|
|
44
|
+
- No expectation of handler
|
|
45
|
+
- Cannot be rejected (already happened)
|
|
46
|
+
- Asynchronous
|
|
47
|
+
|
|
48
|
+
Query (Interrogative):
|
|
49
|
+
- "GetOrder" - Asks for data
|
|
50
|
+
- Expect response
|
|
51
|
+
- Does not change state
|
|
52
|
+
- Synchronous usually
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Architecture Patterns
|
|
56
|
+
|
|
57
|
+
### 1. Event Notification
|
|
58
|
+
```
|
|
59
|
+
Publisher only notifies that something happened:
|
|
60
|
+
|
|
61
|
+
Order Service Inventory Service
|
|
62
|
+
│ │
|
|
63
|
+
├──▶ Event: OrderPlaced ─────▶│
|
|
64
|
+
│ ├──▶ Update inventory
|
|
65
|
+
│ │
|
|
66
|
+
└──▶ (doesn't wait) └──▶ (independent)
|
|
67
|
+
|
|
68
|
+
Characteristics:
|
|
69
|
+
- Simple notification
|
|
70
|
+
- Consumer decides what to do
|
|
71
|
+
- Very loosely coupled
|
|
72
|
+
- Publisher doesn't know consumers exist
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. Event-Carried State Transfer
|
|
76
|
+
```
|
|
77
|
+
Event contains full state needed:
|
|
78
|
+
|
|
79
|
+
Order Service Reporting Service
|
|
80
|
+
│ │
|
|
81
|
+
├──▶ Event: OrderPlaced ─────▶│
|
|
82
|
+
│ {full order data} ├──▶ Store in read model
|
|
83
|
+
│ │
|
|
84
|
+
└──▶ Consumer has all data └──▶ No need to call back
|
|
85
|
+
|
|
86
|
+
Characteristics:
|
|
87
|
+
- Event contains all needed data
|
|
88
|
+
- Consumer doesn't need to query source
|
|
89
|
+
- Good for read models, analytics
|
|
90
|
+
- Larger event payloads
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Event Sourcing
|
|
94
|
+
```
|
|
95
|
+
Store all state changes as events:
|
|
96
|
+
|
|
97
|
+
Traditional: Event Sourcing:
|
|
98
|
+
┌───────────────────┐ ┌───────────────────┐
|
|
99
|
+
│ Current State │ │ Event Log │
|
|
100
|
+
│ Order: #123 │ │ OrderCreated │
|
|
101
|
+
│ Status: Shipped │ │ ItemAdded │
|
|
102
|
+
│ Total: $99 │ │ ItemAdded │
|
|
103
|
+
└───────────────────┘ │ PaymentReceived │
|
|
104
|
+
│ OrderShipped │
|
|
105
|
+
└───────────────────┘
|
|
106
|
+
|
|
107
|
+
Current State = Replay all events
|
|
108
|
+
|
|
109
|
+
Benefits:
|
|
110
|
+
- Complete audit trail
|
|
111
|
+
- Time travel (state at any point)
|
|
112
|
+
- Easy debugging
|
|
113
|
+
- Append-only (no conflicts)
|
|
114
|
+
|
|
115
|
+
Challenges:
|
|
116
|
+
- Event schema evolution
|
|
117
|
+
- Replay complexity
|
|
118
|
+
- Storage growth
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 4. CQRS (Command Query Responsibility Segregation)
|
|
122
|
+
```
|
|
123
|
+
Separate read and write models:
|
|
124
|
+
|
|
125
|
+
┌───────────────────┐
|
|
126
|
+
Commands ───▶│ Write Side │
|
|
127
|
+
│ (Optimized for │
|
|
128
|
+
│ writes) │
|
|
129
|
+
└─────────┬─────────┘
|
|
130
|
+
│
|
|
131
|
+
│ Events
|
|
132
|
+
▼
|
|
133
|
+
┌───────────────────┐
|
|
134
|
+
Queries ────▶│ Read Side │
|
|
135
|
+
│ (Optimized for │◀── Events update
|
|
136
|
+
│ queries) │ read model
|
|
137
|
+
└───────────────────┘
|
|
138
|
+
|
|
139
|
+
Benefits:
|
|
140
|
+
- Optimized read/write models
|
|
141
|
+
- Scale reads independently
|
|
142
|
+
- Complex queries without affecting writes
|
|
143
|
+
- Different data models for different views
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Event Patterns
|
|
147
|
+
|
|
148
|
+
### Event Producer Patterns
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
1. Event-First Design:
|
|
152
|
+
- Design events before APIs
|
|
153
|
+
- Events are the contract
|
|
154
|
+
- Services react to events
|
|
155
|
+
|
|
156
|
+
2. Event Storming:
|
|
157
|
+
- Domain experts + developers
|
|
158
|
+
- Discover events together
|
|
159
|
+
- Post-it notes on wall
|
|
160
|
+
- Creates ubiquitous language
|
|
161
|
+
|
|
162
|
+
3. Domain Events:
|
|
163
|
+
- Express business facts
|
|
164
|
+
- Meaningful to domain experts
|
|
165
|
+
- "OrderPlaced", "PaymentFailed"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Event Consumer Patterns
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
1. Competing Consumers:
|
|
172
|
+
┌─────────────────────────────────────┐
|
|
173
|
+
│ Event Stream │
|
|
174
|
+
└─────────────────┬───────────────────┘
|
|
175
|
+
│
|
|
176
|
+
┌────────────┼────────────┐
|
|
177
|
+
▼ ▼ ▼
|
|
178
|
+
┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
179
|
+
│Consumer1│ │Consumer2│ │Consumer3│
|
|
180
|
+
│(same │ │(same │ │(same │
|
|
181
|
+
│ group) │ │ group) │ │ group) │
|
|
182
|
+
└─────────┘ └─────────┘ └─────────┘
|
|
183
|
+
|
|
184
|
+
Only one consumer processes each event.
|
|
185
|
+
Enables horizontal scaling.
|
|
186
|
+
|
|
187
|
+
2. Fan-out:
|
|
188
|
+
┌─────────────────────────────────────┐
|
|
189
|
+
│ Event Stream │
|
|
190
|
+
└─────────────────┬───────────────────┘
|
|
191
|
+
│
|
|
192
|
+
┌────────────┼────────────┐
|
|
193
|
+
▼ ▼ ▼
|
|
194
|
+
┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
195
|
+
│ Email │ │ SMS │ │ Analytics│
|
|
196
|
+
│ Service │ │ Service │ │ Service │
|
|
197
|
+
└─────────┘ └─────────┘ └─────────┘
|
|
198
|
+
|
|
199
|
+
Each consumer gets every event.
|
|
200
|
+
Independent processing.
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Message Brokers
|
|
204
|
+
|
|
205
|
+
### Comparison
|
|
206
|
+
```
|
|
207
|
+
┌──────────────┬───────────────┬───────────────┬───────────────┐
|
|
208
|
+
│ Feature │ Kafka │ RabbitMQ │ SQS │
|
|
209
|
+
├──────────────┼───────────────┼───────────────┼───────────────┤
|
|
210
|
+
│ Throughput │ Very High │ Medium │ High │
|
|
211
|
+
│ Latency │ Low │ Very Low │ Medium │
|
|
212
|
+
│ Ordering │ Per partition │ Not guaranteed│ FIFO queues │
|
|
213
|
+
│ Replay │ Yes │ No │ Limited │
|
|
214
|
+
│ Retention │ Configurable │ Until consumed│ Configurable │
|
|
215
|
+
│ Use Case │ Event streaming│ Message queue │ Simple queue │
|
|
216
|
+
└──────────────┴───────────────┴───────────────┴───────────────┘
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Kafka Architecture
|
|
220
|
+
```
|
|
221
|
+
┌─────────────────────────────────────────────────────┐
|
|
222
|
+
│ Kafka Cluster │
|
|
223
|
+
│ ┌─────────────────────────────────────────────┐ │
|
|
224
|
+
│ │ Topic: orders │ │
|
|
225
|
+
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
|
|
226
|
+
│ │ │Partition0│ │Partition1│ │Partition2│ │ │
|
|
227
|
+
│ │ │ │ │ │ │ │ │ │
|
|
228
|
+
│ │ │ msgs... │ │ msgs... │ │ msgs... │ │ │
|
|
229
|
+
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
|
|
230
|
+
│ └─────────────────────────────────────────────┘ │
|
|
231
|
+
└─────────────────────────────────────────────────────┘
|
|
232
|
+
▲ │
|
|
233
|
+
│ Produce │ Consume
|
|
234
|
+
│ │
|
|
235
|
+
┌────────┴────────┐ ┌────────┴────────┐
|
|
236
|
+
│ Producer │ │ Consumer │
|
|
237
|
+
│ (Order Svc) │ │ (Email Service) │
|
|
238
|
+
└─────────────────┘ └─────────────────┘
|
|
239
|
+
|
|
240
|
+
Key Features:
|
|
241
|
+
- Partitioned for scalability
|
|
242
|
+
- Offset-based consumption
|
|
243
|
+
- Long retention (days/weeks)
|
|
244
|
+
- Replay capability
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Event Schema Design
|
|
248
|
+
|
|
249
|
+
### Schema Evolution
|
|
250
|
+
```
|
|
251
|
+
Backward Compatible Changes:
|
|
252
|
+
✅ Add optional field
|
|
253
|
+
✅ Add new event type
|
|
254
|
+
✅ Rename field (with alias)
|
|
255
|
+
|
|
256
|
+
Breaking Changes:
|
|
257
|
+
❌ Remove required field
|
|
258
|
+
❌ Change field type
|
|
259
|
+
❌ Rename field (without alias)
|
|
260
|
+
|
|
261
|
+
Best Practices:
|
|
262
|
+
- Use schema registry
|
|
263
|
+
- Version your schemas
|
|
264
|
+
- Plan for evolution
|
|
265
|
+
- Document changes
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Event Envelope
|
|
269
|
+
```
|
|
270
|
+
Standard event structure:
|
|
271
|
+
|
|
272
|
+
{
|
|
273
|
+
"metadata": {
|
|
274
|
+
"eventId": "uuid",
|
|
275
|
+
"eventType": "OrderPlaced",
|
|
276
|
+
"eventVersion": "1.0",
|
|
277
|
+
"timestamp": "2024-01-15T10:30:00Z",
|
|
278
|
+
"source": "order-service",
|
|
279
|
+
"correlationId": "trace-123",
|
|
280
|
+
"causationId": "command-456"
|
|
281
|
+
},
|
|
282
|
+
"data": {
|
|
283
|
+
// Event-specific payload
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
Metadata enables:
|
|
288
|
+
- Tracing
|
|
289
|
+
- Replay
|
|
290
|
+
- Debugging
|
|
291
|
+
- Routing
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Idempotency
|
|
295
|
+
|
|
296
|
+
### Why Idempotency Matters
|
|
297
|
+
```
|
|
298
|
+
At-least-once delivery means duplicates can occur:
|
|
299
|
+
|
|
300
|
+
Producer ──▶ Event1 ──▶ Consumer
|
|
301
|
+
│
|
|
302
|
+
└──▶ Event1 (retry) ──▶ Consumer
|
|
303
|
+
|
|
304
|
+
Consumer might receive same event twice!
|
|
305
|
+
|
|
306
|
+
Solution: Make processing idempotent
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Idempotency Patterns
|
|
310
|
+
```
|
|
311
|
+
1. Natural Idempotency:
|
|
312
|
+
- Update SET status = 'shipped' WHERE id = 123
|
|
313
|
+
- Running twice = same result
|
|
314
|
+
|
|
315
|
+
2. Idempotency Key:
|
|
316
|
+
- Check if event processed before
|
|
317
|
+
- Store processed event IDs
|
|
318
|
+
- Skip if already processed
|
|
319
|
+
|
|
320
|
+
3. Deduplication Table:
|
|
321
|
+
┌────────────────────────────┐
|
|
322
|
+
│ processed_events │
|
|
323
|
+
├────────────────────────────┤
|
|
324
|
+
│ event_id | processed_at │
|
|
325
|
+
└────────────────────────────┘
|
|
326
|
+
|
|
327
|
+
Before processing:
|
|
328
|
+
IF NOT EXISTS (SELECT 1 FROM processed_events WHERE event_id = ?)
|
|
329
|
+
THEN process and insert
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Challenges & Solutions
|
|
333
|
+
|
|
334
|
+
### 1. Event Ordering
|
|
335
|
+
```
|
|
336
|
+
Problem: Events arrive out of order
|
|
337
|
+
|
|
338
|
+
Solutions:
|
|
339
|
+
- Partition by aggregate ID (Kafka)
|
|
340
|
+
- Sequence numbers + reordering
|
|
341
|
+
- Accept eventual consistency
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### 2. Error Handling
|
|
345
|
+
```
|
|
346
|
+
Problem: What if consumer fails?
|
|
347
|
+
|
|
348
|
+
Strategies:
|
|
349
|
+
- Dead Letter Queue (DLQ)
|
|
350
|
+
- Retry with backoff
|
|
351
|
+
- Skip and log
|
|
352
|
+
- Poison pill handling
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### 3. Monitoring
|
|
356
|
+
```
|
|
357
|
+
What to monitor:
|
|
358
|
+
- Event lag (messages behind)
|
|
359
|
+
- Processing latency
|
|
360
|
+
- Error rates
|
|
361
|
+
- Consumer group status
|
|
362
|
+
- Queue depths
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Use Cases
|
|
366
|
+
|
|
367
|
+
### Best for EDA
|
|
368
|
+
```
|
|
369
|
+
✅ Async workflows (order processing)
|
|
370
|
+
✅ Real-time notifications
|
|
371
|
+
✅ Event sourcing
|
|
372
|
+
✅ Analytics pipelines
|
|
373
|
+
✅ IoT data ingestion
|
|
374
|
+
✅ Audit logging
|
|
375
|
+
✅ Eventual consistency acceptable
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Not Ideal for EDA
|
|
379
|
+
```
|
|
380
|
+
❌ Real-time collaboration (use WebSockets)
|
|
381
|
+
❌ Strong consistency required
|
|
382
|
+
❌ Simple request-response
|
|
383
|
+
❌ Low latency requirements
|
|
384
|
+
❌ Small scale, simple domain
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Further Reading
|
|
388
|
+
|
|
389
|
+
- "Enterprise Integration Patterns" - Gregor Hohpe
|
|
390
|
+
- "Event Streams in Action" - Adam Bellemare
|
|
391
|
+
- "Building Event-Driven Microservices" - Adam Bellemare
|
|
392
|
+
- Event Storming - Alberto Brandolini
|
|
393
|
+
- martinfowler.com/articles/201701-event-driven.html
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# Microservices Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Microservices architecture structures an application as a collection of loosely coupled, independently deployable services.
|
|
5
|
+
|
|
6
|
+
## Core Principles
|
|
7
|
+
|
|
8
|
+
### 1. Single Responsibility
|
|
9
|
+
Each service does one thing well:
|
|
10
|
+
```
|
|
11
|
+
❌ Bad: UserOrderPaymentService
|
|
12
|
+
✅ Good: UserService, OrderService, PaymentService
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Independence
|
|
16
|
+
Services can be:
|
|
17
|
+
- Developed independently
|
|
18
|
+
- Deployed independently
|
|
19
|
+
- Scaled independently
|
|
20
|
+
- Replaced independently
|
|
21
|
+
|
|
22
|
+
### 3. Decentralization
|
|
23
|
+
- Each team owns their service
|
|
24
|
+
- No central coordination needed
|
|
25
|
+
- Polyglot persistence possible
|
|
26
|
+
- Technology flexibility
|
|
27
|
+
|
|
28
|
+
## Service Decomposition
|
|
29
|
+
|
|
30
|
+
### By Business Capability
|
|
31
|
+
```
|
|
32
|
+
Organization:
|
|
33
|
+
- Catalog Team → Catalog Service
|
|
34
|
+
- Order Team → Order Service
|
|
35
|
+
- Shipping Team → Shipping Service
|
|
36
|
+
|
|
37
|
+
Benefits:
|
|
38
|
+
- Aligned with business
|
|
39
|
+
- Stable boundaries
|
|
40
|
+
- Clear ownership
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### By Subdomain (DDD)
|
|
44
|
+
```
|
|
45
|
+
Domain: E-commerce
|
|
46
|
+
|
|
47
|
+
Core Domain:
|
|
48
|
+
- Catalog
|
|
49
|
+
- Pricing
|
|
50
|
+
- Inventory
|
|
51
|
+
|
|
52
|
+
Supporting:
|
|
53
|
+
- Shipping
|
|
54
|
+
- Payment
|
|
55
|
+
- Notification
|
|
56
|
+
|
|
57
|
+
Generic:
|
|
58
|
+
- Authentication
|
|
59
|
+
- Reporting
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Decomposition Patterns
|
|
63
|
+
|
|
64
|
+
#### 1. Decompose by Verb (Use Case)
|
|
65
|
+
```
|
|
66
|
+
Services organized by actions:
|
|
67
|
+
- ShipOrderService
|
|
68
|
+
- ProcessPaymentService
|
|
69
|
+
- SendNotificationService
|
|
70
|
+
|
|
71
|
+
Good for: Utility services, operations
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### 2. Decompose by Noun (Resource)
|
|
75
|
+
```
|
|
76
|
+
Services organized by resources:
|
|
77
|
+
- OrderService
|
|
78
|
+
- CustomerService
|
|
79
|
+
- ProductService
|
|
80
|
+
|
|
81
|
+
Good for: CRUD-heavy domains
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Communication Patterns
|
|
85
|
+
|
|
86
|
+
### Synchronous (Request-Response)
|
|
87
|
+
```
|
|
88
|
+
┌─────────┐ HTTP/gRPC ┌─────────┐
|
|
89
|
+
│ Service │────────────▶│ Service │
|
|
90
|
+
│ A │◀────────────│ B │
|
|
91
|
+
└─────────┘ Response └─────────┘
|
|
92
|
+
|
|
93
|
+
Protocols:
|
|
94
|
+
- REST (HTTP/JSON)
|
|
95
|
+
- gRPC (Protocol Buffers)
|
|
96
|
+
- GraphQL
|
|
97
|
+
|
|
98
|
+
Pros: Simple, immediate feedback
|
|
99
|
+
Cons: Coupling, latency, cascading failures
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Asynchronous (Message-Based)
|
|
103
|
+
```
|
|
104
|
+
┌─────────┐ ┌─────────┐
|
|
105
|
+
│ Service │ │ Service │
|
|
106
|
+
│ A │ │ B │
|
|
107
|
+
└────┬────┘ └────┬────┘
|
|
108
|
+
│ │
|
|
109
|
+
│ ┌─────────────┐ │
|
|
110
|
+
└──▶│Message Queue│◀───┘
|
|
111
|
+
└─────────────┘
|
|
112
|
+
|
|
113
|
+
Protocols:
|
|
114
|
+
- AMQP (RabbitMQ)
|
|
115
|
+
- Kafka
|
|
116
|
+
- SQS/SNS
|
|
117
|
+
- EventBridge
|
|
118
|
+
|
|
119
|
+
Pros: Decoupling, resilience, scaling
|
|
120
|
+
Cons: Complexity, eventual consistency
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Data Management
|
|
124
|
+
|
|
125
|
+
### Database per Service
|
|
126
|
+
```
|
|
127
|
+
┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
128
|
+
│ Service │ │ Service │ │ Service │
|
|
129
|
+
│ A │ │ B │ │ C │
|
|
130
|
+
└────┬────┘ └────┬────┘ └────┬────┘
|
|
131
|
+
│ │ │
|
|
132
|
+
▼ ▼ ▼
|
|
133
|
+
┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
134
|
+
│ DB-A │ │ DB-B │ │ DB-C │
|
|
135
|
+
│PostgreSQL│ │ MongoDB │ │ Redis │
|
|
136
|
+
└─────────┘ └─────────┘ └─────────┘
|
|
137
|
+
|
|
138
|
+
Benefits:
|
|
139
|
+
- Independent scaling
|
|
140
|
+
- Technology fit
|
|
141
|
+
- Fault isolation
|
|
142
|
+
- Team autonomy
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Shared Data Patterns
|
|
146
|
+
|
|
147
|
+
#### API Composition
|
|
148
|
+
```
|
|
149
|
+
Query: Get order with customer and product details
|
|
150
|
+
|
|
151
|
+
┌──────────┐
|
|
152
|
+
│ API │──────▶ Order Service (primary)
|
|
153
|
+
│ Gateway │──────▶ Customer Service
|
|
154
|
+
└──────────┘──────▶ Product Service
|
|
155
|
+
│
|
|
156
|
+
▼
|
|
157
|
+
Join results in memory
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### CQRS (Command Query Responsibility Segregation)
|
|
161
|
+
```
|
|
162
|
+
Writes: Reads:
|
|
163
|
+
┌─────────┐ ┌─────────┐
|
|
164
|
+
│ Command │──▶ Write DB │ Query │──▶ Read DB
|
|
165
|
+
│ Side │ │ Side │ (Replica)
|
|
166
|
+
└─────────┘ └─────────┘
|
|
167
|
+
│ ▲
|
|
168
|
+
│ Event Stream │
|
|
169
|
+
└─────────────────────────┘
|
|
170
|
+
|
|
171
|
+
Benefits:
|
|
172
|
+
- Optimized read/write models
|
|
173
|
+
- Scalable reads
|
|
174
|
+
- Complex queries without affecting writes
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Saga Pattern
|
|
178
|
+
```
|
|
179
|
+
Distributed transaction:
|
|
180
|
+
|
|
181
|
+
Order Service → Payment Service → Inventory Service
|
|
182
|
+
│ │ │
|
|
183
|
+
│ Create Order │ │
|
|
184
|
+
├───────────────▶│ │
|
|
185
|
+
│ │ Process Payment │
|
|
186
|
+
│ ├─────────────────▶│
|
|
187
|
+
│ │ │ Reserve Stock
|
|
188
|
+
│◀───────────────┴──────────────────┤
|
|
189
|
+
│ Success │
|
|
190
|
+
|
|
191
|
+
If Payment fails:
|
|
192
|
+
│◀───────────────┤ Cancel Order
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Service Discovery
|
|
196
|
+
|
|
197
|
+
### Client-Side Discovery
|
|
198
|
+
```
|
|
199
|
+
Client queries service registry:
|
|
200
|
+
|
|
201
|
+
┌─────────┐ ┌────────────────┐ ┌─────────┐
|
|
202
|
+
│ Client │────▶│ Service │────▶│ Service │
|
|
203
|
+
│ │ │ Registry │ │ Instance│
|
|
204
|
+
└─────────┘ └────────────────┘ └─────────┘
|
|
205
|
+
│ ▲
|
|
206
|
+
└──────────────────────────────────────┘
|
|
207
|
+
|
|
208
|
+
Examples: Netflix Eureka, Consul
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Server-Side Discovery
|
|
212
|
+
```
|
|
213
|
+
Client goes through load balancer:
|
|
214
|
+
|
|
215
|
+
┌─────────┐ ┌────────────┐ ┌─────────┐
|
|
216
|
+
│ Client │────▶│ Load │────▶│ Service │
|
|
217
|
+
│ │ │ Balancer │ │ Instance│
|
|
218
|
+
└─────────┘ └────────────┘ └─────────┘
|
|
219
|
+
|
|
220
|
+
Examples: AWS ALB, Kubernetes Service, Nginx
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Deployment Patterns
|
|
224
|
+
|
|
225
|
+
### Blue-Green Deployment
|
|
226
|
+
```
|
|
227
|
+
Blue (Current): Green (New):
|
|
228
|
+
┌─────────────┐ ┌─────────────┐
|
|
229
|
+
│ Version │ │ Version │
|
|
230
|
+
│ 1.0 │ │ 2.0 │
|
|
231
|
+
└─────────────┘ └─────────────┘
|
|
232
|
+
▲
|
|
233
|
+
│
|
|
234
|
+
Router
|
|
235
|
+
│
|
|
236
|
+
▼ (switch when ready)
|
|
237
|
+
┌─────────────┐
|
|
238
|
+
│ Version │
|
|
239
|
+
│ 2.0 │
|
|
240
|
+
└─────────────┘
|
|
241
|
+
|
|
242
|
+
Zero downtime, instant rollback
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Canary Deployment
|
|
246
|
+
```
|
|
247
|
+
┌──────────────┐
|
|
248
|
+
│ Router │
|
|
249
|
+
└──────┬───────┘
|
|
250
|
+
│
|
|
251
|
+
┌────────┴────────┐
|
|
252
|
+
│ │
|
|
253
|
+
▼ ▼
|
|
254
|
+
┌─────────────┐ ┌─────────────┐
|
|
255
|
+
│ 90% traffic│ │ 10% traffic│
|
|
256
|
+
│ Version 1.0│ │ Version 2.0│
|
|
257
|
+
└─────────────┘ └─────────────┘
|
|
258
|
+
|
|
259
|
+
Gradual rollout with monitoring
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Challenges & Solutions
|
|
263
|
+
|
|
264
|
+
### Challenge 1: Distributed Transactions
|
|
265
|
+
```
|
|
266
|
+
Solution: Saga Pattern
|
|
267
|
+
- Orchestration: Central coordinator
|
|
268
|
+
- Choreography: Events trigger actions
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Challenge 2: Data Consistency
|
|
272
|
+
```
|
|
273
|
+
Solution: Eventual Consistency + Compensating Actions
|
|
274
|
+
- Accept eventual consistency
|
|
275
|
+
- Design for idempotency
|
|
276
|
+
- Handle conflicts gracefully
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Challenge 3: Testing
|
|
280
|
+
```
|
|
281
|
+
Solution: Testing Strategy
|
|
282
|
+
- Unit tests (within service)
|
|
283
|
+
- Contract tests (between services)
|
|
284
|
+
- Integration tests (end-to-end)
|
|
285
|
+
- Chaos testing (resilience)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Challenge 4: Operational Complexity
|
|
289
|
+
```
|
|
290
|
+
Solution: DevOps Practices
|
|
291
|
+
- CI/CD pipelines
|
|
292
|
+
- Infrastructure as Code
|
|
293
|
+
- Centralized logging
|
|
294
|
+
- Distributed tracing
|
|
295
|
+
- Service mesh (Istio, Linkerd)
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## When to Avoid Microservices
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
❌ Small team (< 10 developers)
|
|
302
|
+
❌ Simple domain
|
|
303
|
+
❌ Early-stage startup
|
|
304
|
+
❌ Limited operational expertise
|
|
305
|
+
❌ Tight deadlines
|
|
306
|
+
❌ Monolithic database required
|
|
307
|
+
❌ Strong transactional requirements
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Further Reading
|
|
311
|
+
|
|
312
|
+
- "Building Microservices" - Sam Newman
|
|
313
|
+
- "Microservices Patterns" - Chris Richardson
|
|
314
|
+
- "Domain-Driven Design" - Eric Evans
|
|
315
|
+
- martinfowler.com/articles/microservices.html
|