---
# System prepended metadata

title: IS213 ESD — Finals Study Reference

---

# IS213 ESD — Finals Study Reference

*Organized by the 10 Revision Groups from W12. Every section maps to lecture modules, mini-cases, and labs signaled by the prof as exam-critical.*

---

## How to use this document

1. **First pass**: read top to bottom, don't memorize — just build the mental map
2. **Second pass**: drill the "X vs Y" tables and scenario triggers (these are the exam questions in disguise)
3. **Third pass**: close this doc, open the HTML quiz app, test recall
4. **Night before**: skim only the red-flag sections marked ⚡

---

# GROUP 1 — Enterprise Applications & Business Processes
*Maps to: W1.2 · Mini Case 1 (Categories)*

## Core concept
A **business process** = a sequence of activities in an enterprise. Each activity often relies on **enterprise applications** (= IT systems = software systems — treated as synonyms in this course). An **enterprise solution** = one or more enterprise applications that produce, process, and exchange data to fulfill business requirements.

Role of an enterprise app in a business process: provide UI · apply business rules · analyze/produce/store/retrieve data · send data to another app.

## ⚡ Three categories of enterprise applications

| Category | Definition | Pros | Cons |
|---|---|---|---|
| **COTS** (Commercial-Off-The-Shelf) | Bought from external vendor, pre-built with best practices, not customer-specific | Out-of-box functionality, reliable, tech support, easier data exchange if standardized APIs | Limited flexibility (vendor owns it), expensive licensing, proprietary tech may block integration |
| **Custom** | Built from scratch (in-house or external devs) per customer specs | Fully tailored, fits exact needs | Expensive, long lead time, documentation-critical, harder to exchange with other enterprises' apps |
| **Legacy** | Old systems (20+ yrs), built with outdated tech | Stable, still provides needed functionality | Incompatible formats/interfaces, hard to integrate with newer apps, expensive to maintain |

## Two persistent challenges (these recur the whole course)
1. How to make apps **easily adaptable** to changing requirements?
2. How to enable **data exchange** among heterogeneous apps?

→ These two challenges are the *reason* SOA/MSA exist.

## Amazon bookstore sample apps (used throughout course)
- **Product Management System** — product details, inventory alerts
- **CRM** — customer details, sales opportunities
- **Accounting** — total price, invoice, financial statements
- **Delivery System** — shipping orders, courier notices

---

# GROUP 2 — Monolith vs Microservice & MSA
*Maps to: W1.3 · W2.1 · W11 Al Hilal · Al Hilal PDF*

## Monolithic Architecture
Three-tier (analogous to MVC): **User Interface + Server + Database**, deployed as a single package (e.g., one `.war`, one PHP folder).

### Monolith characteristics
- Single code base covering all functions
- One programming language, one platform
- Deployment is all-or-none (change one function → redeploy entire app)
- Can't scale one function independently
- Over time becomes large, complex, tightly coupled

## Microservice
**A single unit that implements only one or a few functionalities, usable over the network via a standard interface independent of programming languages and platforms.**

### Microservice characteristics (the "independence" test)
- **Own programming language** (one in Java, another in Python)
- **Own platform** (one on Windows, another on Linux)
- **Own data store** (each with its own DB table when needed)
- **Scaled independently** (deploy extra instances of hot services)
- **Changed independently** (as long as interface stays the same)
- "Loosely coupled" with each other
- Managed by a small agile team (**two-pizza team rule**)

## ⚡ Monolith vs MSA — pros/cons

| Aspect | Monolith | Microservices |
|---|---|---|
| **Coupling** | Tight | Loose |
| **Deployment** | All or none | Each service independently |
| **Scaling** | Whole app | Per-service |
| **Tech diversity** | One stack | Polyglot |
| **Team structure** | Large single team | Many small agile teams |
| **Dev overhead** | Low (function calls) | High (IPC, JSON over HTTP, error handling, network) |
| **CI/CD friendliness** | Low | High |
| **Complexity of interactions** | Internal (simpler to trace) | Across network (harder to test/debug) |
| **Failure modes** | All down together | Partial failures possible |

## ⚡ When is monolith actually better?
- Small/simple app
- Team is small & co-located
- Low need for independent scaling
- "The Monolith Strikes Back" + Amazon Prime Video switching back to monolith (Prime Video saved costs going from serverless microservices back to EC2/ECS monolith) — both cited in glossary as "microservices are not always better"

## Bounded context (for sizing a microservice)
A microservice should be scoped as a **bounded context** (Fowler) around a business entity (Book, Order, Cart, Bill, Payment, Notification). Operations within a context can be coupled; operations across contexts should be loosely coupled.

## CQRS (Command Query Responsibility Segregation) — optional scaling pattern
If reads >> writes (e.g., browsing books vs adding books), split into separate read-microservice + write-microservice with separate DBs. Enables independent scaling at cost of temporary read/write inconsistency.

## ⚡ Al Hilal Bank (AHB) — the W11 case
**Setup:** 2007 Abu Dhabi Islamic bank → 2019 acquired by ADCB → shifted to digital-only retail bank → launched "Al Hilal Digital" super-app Feb 2022.

**Key decisions & why MSA helped:**
- **Super-app business model** (banking + marketplace for food, shopping, travel) → modular microservices for each capability
- **Cloud migration** (on-prem → public cloud, 85% done by June 2023) → microservices fit naturally with cloud scaling
- **Squads** (cross-functional teams w/ daily huddles) → each squad owns a microservice → matches two-pizza rule
- **Cut branch network** → UAE Pass + Emirates Face Recognition for digital onboarding (integration via APIs)
- **DevOps + Agile** → 60 cloud releases in 9 months (was months-per-release under waterfall)
- **12k new customers/month, 1M downloads, 140k accounts** within 12 months of app launch

**Why microservices for AHB specifically:**
- Faster feature delivery (independent deployments per squad)
- Cloud-native scalability (containerize each service, scale hot ones like Customer, Account)
- Partner integration via APIs (reselling insurance, flights, etc. through marketplace)
- Legacy core banking systems integrated via **wrapper services** (Account is a wrapper over legacy)
- Planned "Banking-as-a-Service" → expose APIs to 3rd parties (department stores offering store credit, etc.)

**Four critical success factors (memorize):**
1. Organisational-wide change strategy (top-down leadership from CEO Shakeel)
2. Multi-sided platform (customers ↔ family ↔ UAE gov't identity services ↔ partners)
3. Cloud-based IT infrastructure
4. Rapid execution (Agile + Cloud = weeks, not years)

**AHB SOA layers (from lecture):**
- **UI**: Al Hilal Digital app
- **Composite**: e.g., onboarding flow, family payment features
- **Atomic**: Customer, Payment, Notification
- **Wrapper**: Account (sits on legacy core banking)
- **Legacy/IT Systems**: core banking

## ⚡ Strangler Fig Pattern (W11 — high exam probability)
**Problem:** can't big-bang rewrite a mission-critical legacy system (cf. TSB bank IT meltdown).

**Solution — metaphor**: a strangler fig seeds in upper branches of a host tree, gradually roots downward, eventually strangles & replaces the host.

**Three phases:**
1. **Transform** — identify a capability of the monolith, build a new microservice replicating that capability
2. **Co-exist** — run both old and new; put a **façade** in front to intercept requests and gradually route them to the new service
3. **Eliminate** — once no other part relies on the old capability, decommission it (detect via instrumentation/monitoring)

**Why it works:** incremental, rollback-safe, consumers don't need to know migration happened (façade preserves interface).

---

# GROUP 3 — SOA Design, Atomic/Composite/Wrapper, Bookstore
*Maps to: W2.1 · W2.2 · W7.1 · Mini Case 2 Bookstore · Labs 2+6*

## Service — definition
**A unit that provides one or many functionalities needed to support business requirements and can be used by other applications/services over the network via a standard interface independent of programming languages and platforms.**

- **Service Provider Interface (SPI)** — code at the provider end
- **Service Consumer Interface (SCI)** — code at the consumer end

A monolith's functionality becomes a *service* when it's exposed through a standard interface.

## Service vs Microservice — the key test
A service is a **microservice** if it can be **independently developed and deployed**. Microservice = service + independence criteria from Group 2.

## ⚡ Atomic / Composite / Wrapper

| Attribute | Atomic | Composite | Wrapper |
|---|---|---|---|
| **Independently deployable** | Yes | Yes | No (coupled to underlying system) |
| **Independently scalable** | Yes | Yes | No (depends on underlying) |
| **Encapsulates** | Single "atomic" entity (Customer, Book) | A process (Place Order, Make Payment) | Existing functionality of legacy/external system |
| **Naming** | **Noun** (book, order) | **Verb** (Place Order, Process Shipping) | Often describes the wrapped system |
| **Can invoke other services** | **Never** | **Yes — that's its purpose** | Usually just the wrapped system |
| **Data ownership** | Exclusive owner of its tables | Doesn't own data, requests via APIs | Doesn't own — delegates to wrapped system |
| **Implementation** | CRUD on one entity | Orchestrates/aggregates others via IPC | Function calls into legacy + service interface out |

## Composite Service vs Composite Microservice (⚡ exam trap)
- A **composite service** can (a) directly invoke a monolith's function OR (b) run a long-running process with human intervention
- A **composite microservice** cannot do (a) or (b) — it must be independently scalable
- **Exception**: if the monolith is easily scalable (e.g., a DB behind standard connection URL, or a Google API), a composite service calling it *can* still be called a composite microservice

## Atomic Service "Independence" nuances
- An atomic microservice can use a shared DB or HTTP server (because those are commonly-used, scalable infrastructure)
- Should NOT invoke other microservices via HTTP (that makes it depend on their URLs)
- Can still *send messages out* (e.g., publishing events via AMQP) — but messages shouldn't target a specific receiver
- Can still *reply* when requested (HTTP response, AMQP reply)

## Wrapper service notes
- Often implemented via function calls to the monolith (same language, same machine) → high coupling
- Causes runtime slowdown (extra wrapping operations) — acceptable trade-off
- **Main benefit**: standardization → easier CI/CD + easier replacement later (swap wrapper + monolith for a new microservice with same interface → minimal downtime)
- Wrapper/Adapter/Connector/Plug-in: treated as synonyms in this course

## Bookstore Scenario (Mini Case 2) — standard reference solution
**Entities**: Book, Order, Shipping Record, Activity Log, Error

**Atomic microservices** (CRUD on one entity each):
- `book` (GET all, GET by ISBN, POST new)
- `order` (POST new, GET all, GET by id)
- `shipping_record`
- `activity_log` (often no DB — just logging)
- `error` (often no DB — just printing in lab)

**Composite microservices**:
- `place_order` — orchestrates order creation + shipping record + activity log + error
- `process_shipping_record` — updates shipping status + relevant order

**UI**: Amazing Bookstore UI (customer view + warehouse operator view)

### "Not-so-good" solution vs Good solution (W2.2)
- Bad: the Order atomic service orchestrates everything → it's no longer atomic, it's tightly coupled to business process
- Good: separate `Place an Order` composite microservice orchestrates; Order stays atomic (just CRUD)
- **Takeaway**: business logic belongs in composite, entities stay atomic

## API Documentation
Document each REST endpoint: Resource · Method · URL · Description · Content-type · Input sample.
**Swagger** = industry tool for auto-generating API docs. OutSystems auto-creates Swagger for REST APIs.

## Python/Flask REST template (exam-critical snippet)
```python
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS

app = Flask(__name__)
db = SQLAlchemy(app)
CORS(app)

@app.route("/book/<string:isbn13>")
def find_by_isbn13(isbn13):
    # ... query logic
    return jsonify(result), 200

@app.route("/book", methods=['POST'])
def create_book():
    data = request.get_json()
    # ... create logic
    return jsonify(created), 201

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)
```

---

# GROUP 4 — REST, JSON, HTTP, Networking, Flask
*Maps to: W1.4 · W1.5 · W4.1*

## REST (Representational State Transfer)
Proposed by Roy Fielding (2000 PhD). An architectural style, not a strict protocol.

**Uses standards**: HTTP · URL/URI · JSON/HTML/XML/JPEG · stateless

**REST characteristics**:
- Client-server
- Uniform standardized interface (language & platform agnostic)
- HTTP/HTTPS transport
- Stateless (server doesn't remember previous calls — client sends full context each time)
- Self-describing data
- Layered (proxies, gateways, caches, load balancers in between allowed)

## HTTP methods (exam-critical)

| Method | Intent | CRUD mapping |
|---|---|---|
| **POST** | Create | C |
| **GET** | Retrieve | R |
| **PUT** | Update | U |
| **DELETE** | Delete | D |

## HTTP response status codes (practical subset)
- 200 OK · 201 Created · 400 Bad Request · 404 Not Found · 500 Internal Server Error

## JSON essentials
- Lightweight text-based data-interchange format
- Self-describing, language-agnostic, human-readable
- **Syntax rules**:
  - `{}` = object (unordered name-value pairs)
  - `[]` = array (ordered list)
  - Strings use **double quotes only**
  - Types: number, string, boolean (`true`/`false`), array, object, `null`
  - Name and value separated by `:`
  - Pairs separated by `,`
- Python: `import json; json.loads(str)` / `json.dumps(obj)` / `flask.jsonify(obj)`

### JSON object example
```json
{
  "books": [
    {"availability": 2, "isbn13": "9781129474251", "price": 21.5, "title": "SQL in Nutshell"},
    {"availability": 25, "isbn13": "9781349471231", "price": 99.4, "title": "Understanding People"}
  ]
}
```

## Networking basics

| Concept | One-liner |
|---|---|
| **IP** (IPv4) | 4-byte address, e.g. `192.168.0.101`. Identifies a machine on a network. |
| **Hostname** | Human-readable name, maps to IP via DNS |
| **DNS** | Host-name registry (maps names ↔ IPs) |
| **DHCP** | Dynamically assigns IPs to machines on a LAN |
| **Gateway** | Device connecting a subnetwork to the wider network |
| **Port** | Identifies a process on a machine (e.g., HTTP on 80, SMTP on 25) |
| **localhost / 127.0.0.1** | Loopback — refers to current machine itself |
| **Ping** | Test whether a host is reachable |
| **Load balancer** | Distributes network traffic across multiple servers |
| **Subnet / intranet / internal network** | Private network, often inaccessible from outside |

## NAT (Network Address Translation) — ⚡ tested concept
**What**: maps one network address (IP+port) to another by modifying address info in communication data. Enables cross-network communication.

**Use cases**:
- Home router: internal 192.168.x.x ↔ external public IP
- Docker engine: container internal IPs (172.17.x.x) ↔ host external IP via port forwarding

**Port forwarding / port mapping** = a specific kind of NAT (redirect `host:5000` → `container:5000`).

## Internal vs External IP/Port (Glossary concept)
- Each machine can belong to multiple networks, each with its own IP
- A Docker container has **internal** IP in the Docker virtual subnetwork
- The Docker host has an **external** IP in the physical network
- External clients can't reach containers directly → NAT/port mapping on host relays

---

# GROUP 5 — Docker, Image vs Container, Compose, YAML
*Maps to: W4.1 · W4.2 · Labs 4, 10.1, 10.2, 11*

## Why Docker? The deployment problem
Moving a microservice to another machine breaks because of: wrong Python version · missing modules · DB access fails · DB not running · firewall. Solution: **containerize** — package everything needed into an image.

## Docker — what it is
An open platform to package, transfer, and run microservices (or any app) on any machine, on-premise or in the cloud.

## ⚡ Image vs Container

| | Image | Container |
|---|---|---|
| **What** | File built by `docker build` (layers of software + data, snapshot) | Instance created by `docker run` from an image |
| **Relationship** | 1 image → many containers (each with own state) | 1 container = 1 instance of exactly 1 image |
| **Analogy** | Software program | Running process of that program |
| **Name origin** | Disk image / optical disc image (NOT photo) | Shipping container (standardized cargo) |

## Dockerfile
Text file containing build instructions. Key commands: `FROM`, `COPY`, `RUN`, `CMD`, `EXPOSE`, `ENV`, `WORKDIR`.

## Docker architecture — 3 major components
1. **Docker daemon / engine / server** — the service running on the host, manages images/containers/networks
2. **Docker client** — CLI that talks to the daemon (can be remote)
3. **Docker host** — the machine where daemon runs (has Docker installed)

Each container is essentially a lightweight VM — but shares the host OS kernel (vs full VM which has its own OS → much less overhead).

## VM vs Container (Glossary)
| | Virtual Machine | Docker Container |
|---|---|---|
| **Has own OS?** | Yes (virtual operating system) | No — shares host OS kernel |
| **Overhead** | Heavy (boot an OS) | Light (just start a process) |
| **Isolation** | Strong | Moderate (process-level) |
| **Startup time** | Minutes | Seconds |

## Container networking (⚡ asked every year)
- Each container gets an **internal IP** (typically `172.17.0.x`) in the virtual network created by Docker engine
- Docker engine acts as the **gateway** for containers
- **Same network (container → container)**: use container name as hostname, or internal IP
- **Container → host**: use special hostname `host.docker.internal` (Win/macOS) or host's internal IP
- **External client → container**: must go through the host via **port mapping**
  - e.g., `docker run -p 5000:5000 book` maps host's 5000 → container's 5000

### Port mapping syntax
```
docker run -p <host_port>:<container_port> <image>
```

## Drawbacks of containerization
- Must install Docker on every machine; not compatible with all OSes
- Images take storage; many unused containers = cruft
- Networking among containers is more troublesome than plain machines
- Data is transient by default — must use volumes or `docker commit` to persist
- Need separate tools to manage many containers (Compose, Kubernetes)
- Easier to ship malicious content undetected

## Docker Compose
Tool for defining and running multi-container apps. Uses YAML config.

**Workflow**:
1. Define a `Dockerfile` for each custom image
2. Define services in `docker-compose.yml`
3. Run `docker compose up` (builds + starts everything)

## YAML
"YAML Ain't Markup Language" — human-readable config format.
- Indentation matters (like Python)
- `-` = list item
- `key: value` = map entry
- Superset of JSON

## Sample docker-compose.yml (exam-relevant fragments)
```yaml
services:
  book:
    build:
      context: ./
      dockerfile: Dockerfile
    image: eklum/book:1.0
    container_name: book
    ports:
      - "5000:5000"
    environment:
      - dbURL=mysql+mysqlconnector://is213@host.docker.internal:3306/book
    restart: always
    networks:
      - bookstore-net
    depends_on:
      - dbms
  dbms:
    image: mysql:9.2.0
    ports:
      - "3306:3306"
    networks:
      - bookstore-net
    volumes:
      - bookstore-volume:/var/lib/mysql

networks:
  bookstore-net:
    driver: bridge

volumes:
  bookstore-volume:
```

**What each block does**:
- `services`: list of containers to manage
- `build`: path + Dockerfile for custom image
- `image`: tag for pre-built or built image
- `ports`: `host:container` port mapping
- `environment`: env vars for container
- `depends_on`: startup order
- `networks`: shared network among containers
- `volumes`: persistent storage

## Scaling with Compose
Run multiple instances of one service:
```
docker compose up -d book --scale book=2
```
Or in YAML: `deploy: replicas: 2`

---

# GROUP 6 — Inter-Process Communication (IPC) + HTTP
*Maps to: W5.1 · W5.2 · W7.2 LGB · Lab 5*

## Why IPC matters for MSA
Each microservice runs as a separate process, often on a different machine. They need to communicate constantly → IPC is the glue of MSA.

## ⚡ Communication patterns — 3 axes

### Axis 1: How many receivers?
| Pattern | Meaning | Example |
|---|---|---|
| **One-to-one** | 1 sender → 1 receiver | Mail a letter |
| **One-to-all** | 1 sender → all receivers | Public warning siren |
| **One-to-many** / **one-to-selected** | 1 sender → selected subset | WhatsApp group |

### Axis 2: Does sender expect a reply?
| Pattern | Meaning | Example |
|---|---|---|
| **Fire-and-forget (FF)** | No reply expected | Radio broadcast, anonymous letter |
| **Request-reply (RR)** | Reply expected | Phone call, ordering a book |

### Axis 3: Sender & receiver online simultaneously?
| Pattern | Meaning | Example |
|---|---|---|
| **Synchronous** | Both online at the same time | Phone call |
| **Asynchronous** | Not — uses an intermediary | Email (via email server), voicemail |

## ⚡ Communication technologies

| | Invocation-based | Message-based (Messaging) |
|---|---|---|
| **Data flow** | Point-to-point, directly | Through message broker/intermediary |
| **Typically** | Synchronous | Asynchronous |
| **Examples** | Function call, HTTP, gRPC | AMQP (RabbitMQ), JMS |
| **One-to-many?** | Simulated (loop 1-to-1) | Native via broker |
| **Receiver offline?** | Call fails | Broker stores message |
| **Sender knows receiver?** | Yes (URL/address) | No (only knows broker + routing key) |
| **Coupling** | Tighter | Looser |
| **Maintenance** | None | Must maintain broker |

## ⚡ P1 vs P2 principles (LGB case — heavily tested)
- **P1**: If user/process needs **immediate response** → use **invocation-based, synchronous** communication
  - Rationale: avoid perception of slowness/no reaction
  - Implication: tighter coupling (unless API gateway in middle)
- **P2**: If user/process does **NOT need immediate response** (long-running or async interaction) → use **message-based, asynchronous** communication
  - Rationale: enables loose coupling
  - Implication: added complexity from broker

## Applying P1/P2 — scenario drills (from LGB Ex. 4)
| Scenario | P1 or P2? |
|---|---|
| UI needs to display account balance | **P1** (user is waiting) |
| Composite service needs account balance | **P1** (composite is waiting) |
| UI triggers automated account creation + display result | **P1** |
| Composite service sends notification to customer | **P2** (customer not waiting at that instant) |
| UI triggers appointment booking with bank staff who may not be reachable | **P2** (long-running, needs human) |

## HTTP server-side (Flask)
```python
from flask import Flask, request
@app.route("/book/<string:isbn13>", methods=['POST'])
def create_book(isbn13):
    if request.is_json:
        data = request.get_json()
    else:
        data = request.get_data()
    return isbn13, 200
```

## HTTP client-side (Python requests)
```python
import requests
r = requests.get("http://localhost:5000/book", timeout=1)
print(r.status_code, r.text)

# POST with JSON
r = requests.post(url, json=bookinfo, timeout=1)
# Or generic
r = requests.request('POST', url, json=bookinfo, timeout=1)
```

## Bookstore "Place an Order" — communication pattern breakdown
Looking at the Place an Order composite microservice flow:
- **UI ↔ Place an Order**: 1-to-1, sync RR (user waiting)
- **Place an Order ↔ Order**: 1-to-1, sync RR (composite needs the order ID)
- **Place an Order → Activity Log**: 1-to-1, fire-forget (no reply needed)
- **Place an Order ↔ Shipping Record**: 1-to-1, sync RR (composite needs shipping outcome)
- **If error → Error handler**: 1-to-1, FF
- Combined fail case: **Place an Order → Activity Log + Error** = 1-to-two, FF

Sensible tech choices:
- UI ↔ Place Order, Place Order ↔ Order, Place Order ↔ Shipping Record: **HTTP** (P1)
- Place Order → Activity Log, Error: **AMQP messaging** (P2 — no reply needed, enables 1-to-many)

## HTTP weakness that messaging fixes
HTTP always returns a reply, even if empty → wasteful for fire-and-forget cases. Also harder for 1-to-many. Messaging is cleaner here.

---

# GROUP 7 — Messaging, AMQP, RabbitMQ, Pika
*Maps to: W5.3 · W5.4 · W7.2 LGB · Lab 5*

## MOM (Message-Oriented Middleware)
Software between apps/microservices that lets them exchange data as messages. Overall architecture = **hub-and-spoke** (through a central broker) — contrast with peer-to-peer of HTTP.

## Common message structure (3 parts)
1. **Networking / transport info** (headers, protocol stuff)
2. **Properties / metadata** (key-value pairs: delivery_mode, correlation_id, reply_to)
3. **Body** (actual business data — often JSON)

## AMQP (Advanced Message Queuing Protocol)
- Open standard protocol for MOM
- Defines extensible message format
- Interoperability across AMQP-compliant implementations
- Supports all the comm patterns (1-1, 1-many, FF, RR)

### The AMQP stack in this course
| Layer | Example |
|---|---|
| **Protocol** | AMQP |
| **Broker software** | **RabbitMQ** (implements AMQP) |
| **Python client library** | **pika** |

## ⚡ RabbitMQ core objects
| Object | Role |
|---|---|
| **Producer / Publisher** | Sends messages |
| **Consumer / Subscriber** | Receives messages |
| **Broker** | Accepts, stores, forwards messages (the RabbitMQ server) |
| **Queue** | Named message storage inside the broker (analogy: post box) |
| **Exchange** | Routes messages to queue(s) based on routing/binding keys (analogy: postman) |
| **Routing key** | Set by publisher on each message (e.g., `"order.info"`) |
| **Binding key** | Set when binding a queue to an exchange; can be wildcard pattern |

## Routing logic
1. Publisher sends message **to an exchange** with a **routing key**
2. Exchange matches routing key against binding keys of queues bound to it
3. Message lands in matching queue(s)
4. Subscribers pull from queues they're consuming

## ⚡ Exchange types (exam-critical)

| Exchange | Routing behavior | Best for |
|---|---|---|
| **Direct** | Queue receives if binding key == routing key exactly | **One-to-one** (email → inbox, home mailbox) |
| **Fanout** | Routes to **ALL** queues bound to it (ignores routing key) | **One-to-all** (radio broadcast, group email, news subscription) |
| **Topic** | Wildcard pattern match (routing key vs binding key) | **One-to-selected** (Facebook notification types) |

### Topic wildcards
- `*` matches exactly **one word**
- `#` matches **zero, one, or many words**
- Words separated by `.`
- Examples:
  - `*.error` matches `order.error`, `shipping.error`, but NOT `system.fatal.error`
  - `#.info` matches `info`, `order.info`, `more.order.info`
  - `#` matches ANY key
  - `order.*` matches `order.info`, `order.error`; NOT `order.urgent.error`

### Which exchange for which pattern?
| Communication pattern | Most natural exchange |
|---|---|
| One-to-one | Direct |
| One-to-all | Fanout |
| One-to-selected-many | Topic |
| FF / RR | Any (RR = two one-way messages) |

*Topic can emulate direct or fanout too — it's the most general type.*

## ⚡ Load balancing via queues
If **multiple consumers subscribe to the SAME queue**, messages are distributed round-robin (or random) across them → the queue acts as a load balancer. This is how you horizontally scale a receiver without any extra infra.

## Durability & persistence (glossary terms to know)
- **Durable queue/exchange**: survives broker reboot
- **Persistent message**: `delivery_mode=2` (pika.spec.PERSISTENT_DELIVERY_MODE) — survives broker reboot while on queue
- **Transient message**: `delivery_mode=1` — dropped if no subscriber when it arrives or broker reboots
- **TTL** (time-to-live): how long the message stays alive before expiring

## ⚡ Pika programming model

### Publisher
```python
# 1. Connect
connection = pika.BlockingConnection(...)
# 2. Channel (virtual session)
channel = connection.channel()
# 3. Declare exchange
channel.exchange_declare(exchange='order_topic', exchange_type='topic', durable=True)
# 4. Publish
channel.basic_publish(
    exchange='order_topic',
    routing_key='order.info',
    body=json.dumps(order),
    properties=pika.BasicProperties(delivery_mode=2)  # persistent
)
# 5. Close
connection.close()
```

### Subscriber
```python
# 1. Connect + channel
connection = pika.BlockingConnection(...)
channel = connection.channel()
# 2. Declare exchange + queue
channel.exchange_declare(exchange='order_topic', exchange_type='topic', durable=True)
channel.queue_declare(queue='Activity_Log', durable=True)
# 3. Bind queue to exchange
channel.queue_bind(exchange='order_topic', queue='Activity_Log', routing_key='#')  # receive everything
# 4. Consume
def callback(channel, method, properties, body):
    # process message
    print(body)

channel.basic_consume(queue='Activity_Log',
                      on_message_callback=callback,
                      auto_ack=True)
channel.start_consuming()  # Ctrl+C to stop
```

### ⚡ Role discipline (likely exam point)
- **Publishers** declare exchanges + set routing keys; do NOT declare queues; do NOT know subscribers
- **Subscribers** declare queues + bind them with binding keys; do NOT know publishers

## Scenario: Bookstore Place-an-Order with AMQP
Replace HTTP for FF parts with AMQP:
- `Place an Order` publishes to topic exchange `order_topic`
  - routing key `order.info` on success → goes to `Activity_Log` queue (binding `#`)
  - routing key `order.error` / `shipping.error` on failure → goes to `Error` queue (binding `*.error`) AND `Activity_Log` (binding `#`)

Result: one message can fan out to multiple consumers without the sender knowing them.

---

# GROUP 8 — API Gateway, Kong, myTaxi
*Maps to: W10.1 · W10.2 · W10.3 · Mini Case 3 · Labs 10.2, 11*

## The problem API Gateway solves
When many microservices and many clients exist, clients end up knowing too many URLs/routing keys. A URL change breaks every client. Clients also duplicate logic for auth, monitoring, load balancing, caching.

## API Gateway — definition
A middleware (often a software component) that **manages external access** to microservices. Usually exposes services as REST APIs since REST is the most-used by clients.

**Mental model**: the API Gateway is to HTTP what the Message Broker is to AMQP — a central intermediary that decouples senders and receivers.

## ⚡ 7 functionalities of an API Gateway (exam — memorize)

| # | Functionality | What it does |
|---|---|---|
| 1 | **Routing (URL mapping)** | Maps client request URL → internal service URL. Client uses 1 stable URL; backend URLs can change freely |
| 2 | **Load balancing** | Distributes requests across multiple instances of a service |
| 3 | **Security enforcement** | Authentication, authorization, access control (API keys, ACLs, JWT) |
| 4 | **Monitoring / logging** | Central log of all requests/responses, usage stats |
| 5 | **Caching** | Stores responses for repeated requests, solution-wide benefit |
| 6 | **Versioning** | Routes v1 clients to v1 services, v2 to v2, even transforms between them — enables incremental upgrades |
| 7 | **Aggregation** | Combines responses from multiple services into one (for simple union/concatenation) |

## ⚡ Drawbacks of API Gateway
- **Single point of failure** — its failure brings down everything
- **Performance bottleneck** — extra hop adds latency; must be highly scalable itself
- **Another component** to develop, deploy, manage

## myTaxi case — each exercise's point
The myTaxi mini case walks through 7 needs (one per exercise) + summary. For each need, 3 options are compared:
- **Option 1**: in each client (client-side)
- **Option 2**: in each microservice (service-side)
- **Option 3**: in an API Gateway (central)

**Pattern of the answer**: option 1 is insecure (client code can be tampered) + inefficient (duplicated everywhere) + requires config file updates across all clients; option 2 centralizes per-service but creates duplicate code across services; **option 3 (gateway)** decouples cross-cutting concerns from business logic, centralizing them.

### ⚡ Summary from Ex.8
Issues without a gateway: URL coupling, client-side complexity, duplicated auth/logging/caching, hard to enforce policies, hard to version, hard to expose as open APIs.

With a gateway: routing · load balancing · security · monitoring · caching · versioning · aggregation (the 7 above).

Drawbacks: SPOF · performance overhead · additional component.

## Open APIs (from myTaxi + Al Hilal)
- **Open API** = public API (usually REST) giving programmatic access to 3rd-party apps
- Enable new business opportunities: `myMap`, `myHotel`, `myHandyman` integrating myTaxi booking
- Revenue model: pay 10% commission to partners per booking made via their app
- **Why gateway is almost required**: routing per partner + monitoring to track who booked what + access control via partner-specific API keys + billing attribution

## Kong — the gateway used in labs
Open-source API gateway. Runs in a Docker container.

### Kong concepts (memorize for lab questions)
| Kong object | Meaning |
|---|---|
| **Service (Kong service)** | Abstract representation of an upstream microservice (stores its URL) |
| **Route** | Maps client-facing URL path to the Kong service (like `@app.route` in Flask) |
| **Upstream** | Virtual hostname referencing multiple **targets** for load balancing |
| **Target** | Actual host of a running microservice instance (e.g., `book1:5000`) |
| **Consumer** | Account representing a client/user |
| **Consumer group** | Group of consumers |
| **API key** | Credential for a consumer |
| **ACL** | Which consumer groups can access which services/routes |
| **Plugin** | Adds features (auth, rate-limit, Prometheus metrics, etc.) |

### Kong ports (lab-memory)
- **8000** — HTTP request entry (where clients send requests)
- **8001** — admin API (RESTful config of Kong)
- **8002** — Kong Manager GUI (web admin UI)

### Kong load balancing setup
1. Create an **upstream** (virtual hostname)
2. Add multiple **targets** (e.g., `book1:5000`, `book2:5000`)
3. Change the **service's** host to point to the upstream (instead of a target)
4. Kong distributes requests across targets

### Kong + Docker Compose for replicas
Can also scale via `docker compose up -d book --scale book=2`, or put `deploy: replicas: 2` in YAML.

### Kong monitoring stack
- Kong **Prometheus plugin** exposes metrics on port **9090**
- **Prometheus** server scrapes and stores time-series data
- **Grafana** (port 3000) connects to Prometheus for visualization dashboards
- For AHB: this is the "BTL extension" pattern — also used in BloodLink

---

# GROUP 9 — SOA Layers, LGB Case, Al Hilal (revisit), P1/P2, Strangler Fig
*Maps to: W2.1 · W7.1 · W7.2 · W11 · Labs 7, 10.1*

## ⚡ SOA vs MSA (big picture)

| | SOA | MSA |
|---|---|---|
| **Service size** | Any — small or big monolithic | Small, independently deployable |
| **Includes monoliths?** | Yes, wrapped | Discouraged (only via wrappers) |
| **Tech stack** | Often shared (ESB, SOAP) | Polyglot (REST, messaging) |
| **Dev teams** | Often centralized | Small autonomous squads |
| **Principle** | Services with standard interfaces | Services with standard interfaces + strict independence |

If an SOA has only small independently-deployable services with standard interfaces, it IS an MSA.

## ⚡ Sample SOA layers (the standard diagram)

From top (user) to bottom (data):

1. **User Interface Layer** — screens, apps
   - Triggers processes; can invoke service layers (not monoliths)
2. **Business Process / Composite Layer(s)**
   - Straight-through composites (automated flows like "Place an Order")
   - Long-running composites (involve human steps, e.g., loan approval)
3. **Atomic Microservice Layer**
   - Independently scalable, one-entity-focused
   - Do NOT communicate with other atomic services directly
4. **Wrapper Service Layer**
   - Expose legacy/external/monolith functionality as services
5. **IT Systems Layer**
   - COTS, custom, legacy apps. Do NOT communicate with other layers directly
6. **External Services Layer**
   - 3rd-party services (Google, Stripe), may or may not be microservices

**Cross-cutting infrastructure**: API Gateway · Enterprise Service Bus (ESB) · Business Process Management · Message Broker · Container Management

### The rules to remember
- Higher layers reuse lower layers' functionality
- UI **never** talks to IT Systems directly — only via services
- Atomic microservices **never** call other atomic services (that's the composite's job)
- IT Systems **never** talk directly to UI/composites — only via wrappers

## ⚡ LGB Bank Case — "Issue Insurance Policy" (most likely exam case)

### Setup
LGB Bank is a reseller of Travel Insurance from INSCO. Previously 3-day batch processing. Choice: new monolith OR compose existing microservices. Chose composite microservices.

### LGB's existing atomic microservices (memorize)
- **Deposit Account** (CRUD + publish Deposit Event)
- **Card Account** (CRUD + Card Event)
- **Insurance Account** (CRUD only)
- **Limit** (Get/Update + Limit Event)
- **Fee** (Get/Update)
- **Exchange Rate** (Get only)
- **Loyalty Points** (Add/Get/Redeem + Loyalty Event)
- **Journal Entry** (subscribes to all events, creates journal entries)
- **Notification** (subscribes to events needing customer alerts, sends SMS/Email)

### INSCO atomic microservices (external — wrapper-like)
- **Insurance Plan** (Get plans) — marketing details, no pricing
- **Insurance Premium** (Calculate) — given plan + payment option → premium amount
- **Insurance Proposal** (Create) — given plan + premium → proposal ID
- **Insurance Policy** (Create) — given proposal + customer → policy ID

### The 5-step Issue Travel Insurance flow
1. **Get Insurance Plans** — UI → INSCO (direct) — **P1** (user browsing)
2. **Calculate Insurance Premium** — UI → INSCO — **P1** (user waiting)
3. **Get Payment Methods** — UI → composite **aggregates** Deposit + Card + Loyalty — **P1** (user about to pay)
4. **Create Insurance Proposal** — UI → INSCO — **P1** (user waiting for proposal to review)
5. **Issue Insurance Policy** — UI → composite **orchestrates**:
   1. Create Insurance Account
   2. Make Payment (another composite — orchestrates Deposit, Card, Fee, Exchange, Loyalty via sync HTTP; publishes Payment Event to Journal + Notification via async AMQP)
   3. Create Insurance Policy (INSCO)
   4. Update Insurance Account with policy ID
   5. Publish Policy Event (to Journal + Notification via AMQP)
   — **P1** for user-waiting parts, **P2** for Journal/Notification (user doesn't need to wait for an SMS)

### Pattern: Aggregation vs Orchestration
- **Get Payment Methods** = **Aggregation** (parallel calls, combine responses, return to caller)
- **Issue Insurance Policy** = **Orchestration** (ordered steps, each may depend on previous, may involve rollback logic)
- **Make Payment** = nested composite microservice (composite calls composite) — reusable for any payment process

### Conclusion of LGB case
- No new atomic microservices needed — pure composition
- New composites reusable: Get Payment Methods → Grab Pay; Make Payment → any fund transfer; Issue Insurance Policy → any insurance type
- 3-day batch → near real-time via composite orchestration

## ⚡ Orchestration vs Choreography

| | Orchestration | Choreography |
|---|---|---|
| **Control** | Central controller (composite service) dictates sequence | No controller — each service reacts to events |
| **Suitable when** | Sequential / specific order, need consolidated results | Order is uncertain, no single consolidation point needed |
| **Rollback** | Easier (controller knows what happened) | Harder (distributed state) |
| **Typical tech** | Invocation-based (HTTP, RPC) | Message-based (AMQP, events) |
| **Coupling** | Tighter (controller knows all participants) | Looser (emit event, receivers subscribe) |
| **Failure handling** | Fail fast, central decision | Eventual consistency |
| **Analogy** | Conductor directs orchestra | Dancers follow cues from each other |

*Technically you can implement choreography with HTTP and orchestration with messaging — the choice is about coupling, not just tech.*

## Implementation steps for any business process in MSA (checklist for case study questions)
1. **Define the business process** (what activities, what triggers, what outcomes)
2. **Identify services** — atomic, wrapper, composite
   - Reuse existing? Or develop new?
3. **Compose interactions**:
   - Pick **communication patterns** (1-1 vs 1-many; FF vs RR; sync vs async)
   - Pick **technologies** (apply P1/P2 — HTTP for immediate-response, AMQP for async)
   - Pick **composition style** (orchestration vs choreography)
4. **Layer the architecture** (do we need a UI layer? Which composites belong in the process layer?)
5. **Supporting tools** (API gateway? Docker? Message broker?)

---

# GROUP 10 — OutSystems (LCAP)
*Maps to: W3.1 · W3.2 · W3.3 · Labs 3, 7*

## LCAP (Low Code Application Platforms) — attributes
- Develop commercial-grade, full-stack apps with low/no coding
- GUI Designer Studio — drag-n-drop + configure
- One-click publish to cloud runtime
- Fully managed Dev/Test/Prod by LCAP provider
- Very expensive enterprise licensing — governments, banks, telcos
- In Singapore: all gov agencies use LCAP for new apps; SingTel/StarHub adopting; SMU IT builds internal apps with LCAP; SMU has OutSystems spinoff Narfin

## Gartner: OutSystems in Leader Quadrant for LCAP for years.

## ⚡ Low Code vs Traditional Coding (exam table)

| | Traditional Coding | Low Code (OutSystems) |
|---|---|---|
| **Licensing cost** | Low/none (open source, some DB licenses) | High (>$1M/yr for large orgs) |
| **Infrastructure cost** | High (AWS for Dev/Test/Prod, API gateway, etc.) | None (managed) |
| **Developers needed** | High | ~1/3 the number |
| **Infra/DB engineers** | At least 2 per hosted app | None |
| **Code repo, version ctrl, CI/CD** | GitHub | Built in |
| **Packaging & deployment** | Docker, Kubernetes | 1-click publish |
| **Full stack** | Yes | Yes |
| **Standards (JSON/REST, OAuth)** | Yes | Yes |
| **Speed of development** | Baseline | ~3× faster |
| **Ease of maintenance** | Baseline | Easy (logic is visual) |

## Software Engineering principles still apply in LCAP
- **Separation of Concerns** — frontend/backend split, REST/Swagger as "service contract"
- **Encapsulation** — group related logic in "service boundaries"
- **Reuse** — design services as reusable building blocks
- **SOA Layered Architecture** still applies (UI · Composite · Atomic · Wrapper)

## OutSystems Designer Studio — 4 layers

### Data Layer
- **Database Entities** — auto ER diagrams, auto CRUD, auto DB (MSSQL by default). Bootstrap from Excel
- **Static Entities** — read-only, developer-setup, for enumerations (role types, document types)
- **Structures** — developer-defined data types; for REST APIs, Structure = JSON object; List of Structures = JSON array. **Attribute names are case-sensitive** (must match `Name in JSON` config)
- **Client Variables** — browser-side memory, not persisted at server; only primitive types; Structures must be serialized (JSON → Text) before storing
- **Site Properties** — server-side, application scope, global params, changeable at runtime via Service Center (no republish needed)
- **Resources** — static files (favicon, custom JS/CSS, Excel bootstraps)

### Logic Layer
- Client-side logic runs in browser (emits React.JS)
- Server-side logic runs on server (emits C# .NET)
- Expose/consume REST APIs (Swagger auto-generated)

**Built-in Client Widgets (for UI screens)**:
- Message, Run Client Action, Run Server Action, Refresh Data, If, Switch, For Each, Assign, JSON Serialize, JSON Deserialize, Exception Handler, Raise Exception, Destination, Download, JavaScript

**Built-in Server Widgets**:
- Run Server Action, Aggregate (SELECT on Entity → List), SQL (any SQL), If, Switch, For Each, Assign, Record List to Excel, Excel to Record List, JSON Serialize/Deserialize, Exception Handler, Raise Exception, Comment, Send Email (use SMULab wrapper instead)

**For Each attributes** (when iterating a List):
- `Current` — current iteration value
- `CurrentRowNumber` — index
- `Length` — total items
- `BOF` / `EOF` — at beginning / past end (booleans)
- `Empty` — true if list is empty

**List actions**: ListAll, ListAny, ListAppend, ListAppendAll, ListClear, ListDistinct, ListDuplicate, ListFilter, ListIndexOf, ListInsert, ListRemove, ListSort

**User Functions**: any Client Action can be marked as `Function = Yes` to make it callable via the Expression Editor.

### Interface Layer
- Deployment options: Reactive Web App, PWA Mobile
- Layout templates: Side Menu, Top Menu, etc.
- Drag-n-drop: Dropdowns, Buttons, Checkboxes, Radio Buttons, Inputs, Tables
- Event handlers: OnClick, OnFocus, OnBlur, OnKeyUp, OnKeyDown
- Client Actions run browser-side logic

### Processes Layer
- Orchestrate/subscribe to messaging, e.g., RabbitMQ (ConsumeMessage every 100ms)
- Handle exceptions via Exception Handler chain

## OutSystems can do everything for ESD scope
- ✅ Develop data models / host databases (MSSQL by default)
- ✅ Expose REST APIs (auto Swagger docs)
- ✅ Consume REST APIs
- ✅ Develop UIs (web + PWA mobile)
- ✅ Develop business logic (visual)
- ✅ Subscribe to RabbitMQ

## OutSystems Forge (plugins)
Downloadable components: OpenAI, Google Maps, WhatsApp, Stripe, Speech Recognition, Bitcoin, Coinbase.

## SMULab Utilities (wrapper services for student projects)
Pre-built wrapper services — e.g., for storing content/images. Some require API keys registered per project team.

## Who uses OutSystems at SMU?
- SMU IT: internal apps (Purchase Order System, Facilities Booking, COI Declaration, PGP Admissions)
- SMU FYP students: banking apps (IB, Corporate IB, etc.)
- Narfin (SMU spinoff): Treasury Management, FX Hedging, Digital Client Onboarding with Singpass + facial recognition + CDD

---

# APPENDIX A — Glossary of "X vs Y" distinctions (catchall)

## IT System vs Application vs Enterprise System vs Business App
All synonyms for this course. In practice:
- Systems > applications (systems include hardware)
- Enterprise > business (enterprise = the whole org)

## Software vs Application vs Program
All synonyms for this course. In practice:
- Software = broadest (any computer programs)
- Application = user-focused software (Windows itself isn't an app)
- Program = specific instructions (developers' term)

## Solution vs Application
- Application = specific functionality
- Solution = holistic — design, impl, deployment, maintenance, hardware, software, processes

## Service vs Web Service vs REST Service
- REST service = web service using HTTP + flexible data formats + stateless
- Web service = service accessible over web/network (not necessarily internet — could be internal)
- REST services = REST APIs (synonyms)

## Service vs API
- API = very broad; any invocable interface (Python module APIs are APIs but not services)
- Service = standardized API over a network, language/platform-agnostic
- Treated as synonyms in this course

## Service vs Interface
- "Interface" is overloaded — UI, function interface, API
- Service = standardized API
- Service can refer to interface + implementation; interface is just interface

## Data Exchange / Transfer / Transmission / Communication / Transport
All synonyms in this course. In practice:
- Exchange = possibly among multiple parties
- Transfer/Transmission = one-way
- Transport = also method/technique
- Communication = meaningful exchange w/ mutual understanding

## Data Format vs Data Model
Synonyms in course. Format = computer representation (JSON, HTML); model = concepts+meanings in business context. A model must be expressed in some format.

## Data Transformation / Translation / Formatting / Changes
Synonyms in course. Translation = language/medium/format change; transformation = big change; formatting = syntactic/small; changes = colloquial.

## Internet / Network / Intranet / Extranet
- Internet = big public network (WWW)
- Intranet = internal private org network
- Extranet = org-owned but accessible to external authorized users (vendors, partners)
- External network = everything NOT owned by the org (≠ extranet)
- Subnetwork = logical division of a network

## Virtual Network vs Network
Virtual network = software-driven, built on physical networks. VPN is example.

## Machine vs Host
- Machine = physical computer
- Host = any system that runs/hosts something (can be virtual)
- Local host = machine you're using
- Remote host = server machine you're not physically at

## Microservice vs Database
- Each microservice should have its own **database** (not necessarily own DBMS)
- Multiple microservice DBs can live in one DBMS as long as each has exclusive ownership of its tables
- **Polyglot persistence** — use different DB types for different microservices (geo-spatial DB for location service, ElasticSearch for search service, etc.)

## Database / Schema / Table / DBMS / Data Store
- DB = organized collection of data (tables + schemas + data)
- Schema = structure/blueprint (DB schema, table schema, JSON schema, etc.)
- Table = schema + stored data
- DBMS = software that manages DBs (e.g., MySQL)
- Data Store = generic term for any data storage

---

# APPENDIX B — ⚡ SCENARIO QUICK-DRAW CHEATSHEET

When you see these prompts, trigger these answers:

| Prompt says... | Answer with... |
|---|---|
| "User is waiting for a response" | **P1** → sync HTTP invocation |
| "Long-running / no immediate response needed" | **P2** → async AMQP messaging |
| "Send notification/log (user not waiting)" | **P2** → AMQP FF |
| "Receiver might be offline" | AMQP (broker stores message) |
| "Multiple receivers of same message" | AMQP fanout or topic |
| "One-to-one request-reply" | Direct exchange (or HTTP) |
| "One-to-all broadcast" | Fanout exchange |
| "One-to-selected-many" | Topic exchange |
| "Load balance multiple receivers" | Multiple consumers on same AMQP queue (round-robin) OR API Gateway load balancing across HTTP instances |
| "Legacy system, hard to change, can't deploy independently" | **Wrapper service** |
| "Orchestrates multiple services for a business process" | **Composite microservice** (verb name) |
| "CRUD on one data entity" | **Atomic microservice** (noun name) |
| "Client needs to know many URLs" | **API Gateway** for routing |
| "Need auth/logging/rate-limiting for many services" | **API Gateway** (cross-cutting concerns) |
| "Multiple versions of clients in the wild" | API Gateway **versioning** |
| "Big-bang rewrite of legacy is too risky" | **Strangler Fig pattern** |
| "Co-exist old + new during migration" | Strangler Fig: build façade → co-exist → eliminate |
| "Too many container URLs to remember / manage" | **Docker Compose + API Gateway** |
| "Container can't be reached from outside" | **Port mapping** (`-p host:container`) |
| "Container needs to reach the host machine" | `host.docker.internal` hostname |
| "Team small enough to be fed by two pizzas" | That's the **microservice sizing heuristic** |
| "Independent scaling needed" | Microservice (monolith can't) |
| "Quickly scale one hot function" | Multiple instances of that microservice + load balancer (Kong upstream / queue-based) |
| "Sequential process with rollback" | **Orchestration** |
| "Event-driven, unknown order" | **Choreography** |
| "Aggregate data from multiple services" | Composite microservice (aggregation pattern) OR API Gateway aggregation |
| "Expose service to 3rd parties with billing/tracking" | **API Gateway with Open APIs** |

---

# APPENDIX C — Quick command & code reference

## Flask minimal REST
```python
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS

app = Flask(__name__)
db = SQLAlchemy(app)
CORS(app)

@app.route("/resource/<string:id>")
def get_one(id):
    return jsonify({...}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)
```

## Python requests client
```python
import requests
r = requests.get(url, timeout=1)
r = requests.post(url, json=data, timeout=1)
r = requests.request('POST', url, json=data, timeout=1)
print(r.status_code, r.text)
```

## Pika publisher
```python
channel.exchange_declare(exchange='X', exchange_type='topic', durable=True)
channel.basic_publish(exchange='X', routing_key='a.b',
                      body=json.dumps(data),
                      properties=pika.BasicProperties(delivery_mode=2))
```

## Pika subscriber
```python
channel.queue_declare(queue='Q', durable=True)
channel.queue_bind(exchange='X', queue='Q', routing_key='a.*')
channel.basic_consume(queue='Q', on_message_callback=cb, auto_ack=True)
channel.start_consuming()
```

## Docker commands
```bash
docker build -t myimage:1.0 .
docker run -p 5000:5000 -e dbURL=... myimage:1.0
docker ps
docker stop <container_id>
docker rm <container_id>
docker compose up -d
docker compose up -d book --scale book=3
docker compose down
```

## HTTP methods mnemonic
**P**OST = Put-new (Create) · **G**ET = Get (Read) · **P**UT = Put-change (Update) · **D**ELETE = (Delete)

## Topic exchange wildcards
`*` = exactly one word · `#` = zero, one, or many words · words separated by `.`

---

# APPENDIX D — Final Exam Strategy

## Question patterns to expect
1. **"What is X?"** → definition questions. Short, precise. Use the exact definition from the Glossary.
2. **"X vs Y"** → table-style comparison. Pick 3–5 distinguishing dimensions.
3. **"Given this scenario, design/improve the architecture"** → apply the Implementation Steps Checklist (Group 9).
4. **"What communication pattern/tech/exchange/etc. fits?"** → use the Scenario Cheatsheet (Appendix B).
5. **"Pros and cons of option A vs B"** → follow myTaxi case framing (client vs service vs gateway).
6. **Case-study application** (AHB, LGB, myTaxi, Bookstore) → identify service types (atomic/composite/wrapper), apply P1/P2, layer the architecture, discuss Strangler Fig if legacy migration.

## Common traps
- Calling a composite service "atomic" because it's small
- Forgetting that **atomic services don't call other services** — only composite do
- Saying "API Gateway" when the problem is purely internal service-to-service (ESB or message broker fits there)
- Using HTTP for one-to-many (awkward — messaging is better)
- Confusing P1 and P2 — always ask "is the user/process waiting right now?"
- Calling an atomic service a microservice even if it's tightly coupled to a legacy system — that's a wrapper
- Saying "Docker container" when asked for "Docker image" — image is the file, container is the running instance

## Night-before checklist
- [ ] Atomic/Composite/Wrapper table (memorize)
- [ ] P1/P2 trigger words (memorize)
- [ ] Exchange types + wildcard rules (memorize `*` and `#`)
- [ ] SOA layer order (UI → Composite → Atomic → Wrapper → IT Systems)
- [ ] 7 gateway functionalities + 3 drawbacks
- [ ] Strangler Fig 3 phases (Transform → Co-exist → Eliminate)
- [ ] LGB 5-step flow and where P1/P2 apply
- [ ] AHB 4 critical success factors
- [ ] Docker image vs container distinction
- [ ] Microservice "independence" checklist (5 items)

Good luck.
