|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8" /> |
|
<title>Microservices and Beyond Fact or Fiction (2025)</title> |
|
<link rel="preconnect" href="https://fonts.gstatic.com" /> |
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;600&display=swap" rel="stylesheet"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
|
<style> |
|
* { margin: 0; padding: 0; box-sizing: border-box; } |
|
:root { |
|
--bg1:#ffe0e0; --bg2:#e0f7ff; --ink:#222; --ink-sub:#555; |
|
--brand:#1e3a8a; --brand-2:#2563eb; --good:#16a34a; --bad:#dc2626; |
|
--card:#ffffffcc; |
|
} |
|
body { |
|
font-family: 'Poppins', sans-serif; |
|
background: radial-gradient(1200px 600px at 20% 0%, var(--bg1), transparent 60%), |
|
radial-gradient(1200px 600px at 80% 0%, var(--bg2), transparent 60%), |
|
#f6f7fb; |
|
min-height: 100vh; |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
justify-content: flex-start; |
|
padding: 2rem 1rem; |
|
color: var(--ink); |
|
} |
|
h1 { text-align: center; margin-bottom: .25rem; font-weight: 600; font-size: 2.2rem; } |
|
#subtitle { text-align:center; margin-bottom:1rem; color: var(--ink-sub); } |
|
#source-link { text-align: center; margin-bottom: 1.25rem; font-size: .95rem; } |
|
#source-link a { color: var(--ink); text-decoration: underline; } |
|
#game-container { |
|
background: var(--card); |
|
width: 100%; max-width: 920px; |
|
padding: 2rem; border-radius: 16px; |
|
box-shadow: 0 10px 24px rgba(0,0,0,.15); |
|
display: flex; flex-direction: column; align-items: center; |
|
} |
|
.progress-container { |
|
width: 100%; background:#ececec; border-radius: 999px; overflow: hidden; margin-bottom: 1rem; |
|
} |
|
.progress-bar { height: 14px; width:0%; background: linear-gradient(90deg,var(--brand),var(--brand-2)); transition: width .3s ease; } |
|
#statement { |
|
font-size: 1.25rem; line-height: 1.5; text-align: center; color: #333; |
|
min-height: 90px; margin: .75rem 0 1rem; |
|
} |
|
.btn-group { display:flex; gap:.75rem; flex-wrap:wrap; justify-content:center; margin: .25rem 0 1rem; } |
|
button { |
|
padding: .75rem 1.25rem; border: none; border-radius: 999px; cursor: pointer; |
|
background: var(--brand); color: #fff; font-weight: 600; letter-spacing:.2px; |
|
transition: transform .15s ease, box-shadow .15s ease, background .2s ease; |
|
} |
|
button.secondary { background:#111827; } |
|
button:hover { transform: translateY(-2px); box-shadow: 0 8px 18px rgba(0,0,0,.15); } |
|
#result { |
|
margin-top: .5rem; padding: .75rem 1rem; border-radius: 10px; font-weight: 700; text-align: center; display:none; |
|
} |
|
#result.correct { display:block; background:#dcfce7; color:#14532d; } |
|
#result.incorrect { display:block; background:#fee2e2; color:#7f1d1d; } |
|
#explanation { |
|
margin-top: .75rem; padding: 1rem; background:#f9fafb; color:#374151; border-radius:12px; display:none; |
|
} |
|
#score { margin-top: .75rem; font-weight: 700; } |
|
#controls { display:flex; gap:.5rem; margin-top:.5rem; } |
|
#controls button { background:#0f766e; } |
|
#restart-btn { background:#6b21a8; } |
|
</style> |
|
</head> |
|
<body> |
|
<h1>Microservices and Beyond Fact or Fictions</h1> |
|
<div id="subtitle">Test your knowledge of Monoliths, SOA, Containers, Serverless, and Microservices (2025)</div> |
|
<div id="source-link"> |
|
Source: <a href="https://www.linkedin.com/pulse/transitioning-microservices-concepts-challenges-best-practices-mboke/" target="_blank" rel="noopener"> |
|
Transitioning to Microservices: Concepts, Challenges & Best Practices (LinkedIn) |
|
</a> |
|
</div> |
|
|
|
<div id="game-container" role="region" aria-label="Fact or Fiction game"> |
|
<div class="progress-container" aria-hidden="true"><div class="progress-bar" id="progress-bar"></div></div> |
|
<div id="statement" aria-live="polite">Loading statement...</div> |
|
|
|
<div class="btn-group"> |
|
<button onclick="guess(true)" aria-label="Choose Fact">Fact</button> |
|
<button class="secondary" onclick="guess(false)" aria-label="Choose Fiction">Fiction</button> |
|
</div> |
|
|
|
<div id="result" role="status" aria-live="polite"></div> |
|
<div id="explanation"></div> |
|
|
|
<div id="controls"> |
|
<button id="next-btn" style="display:none;" onclick="nextStatement()">Next</button> |
|
<button id="restart-btn" style="display:none;" onclick="startGame()">Restart</button> |
|
</div> |
|
|
|
<div id="score" aria-live="polite"></div> |
|
</div> |
|
|
|
<script> |
|
|
|
const statements = [ |
|
|
|
{ |
|
text: "Microservices are independently deployable services that each map to a specific business capability.", |
|
isFact: true, |
|
explanation: "Fact. The article defines microservices as fine-grained, independent units aligned to business needs." |
|
}, |
|
{ |
|
text: "Containers package code and all dependencies to provide consistent behavior across dev, test, and prod.", |
|
isFact: true, |
|
explanation: "Fact. Containers encapsulate libraries, frameworks, and runtimes to ensure portability and consistency." |
|
}, |
|
{ |
|
text: "Serverless (FaaS) shifts infrastructure management to the cloud provider so teams can focus on code.", |
|
isFact: true, |
|
explanation: "Fact. Platforms like AWS Lambda/Azure Functions handle provisioning, scaling, and availability." |
|
}, |
|
{ |
|
text: "Excessive inter-service communication in microservices can add latency and operational overhead.", |
|
isFact: true, |
|
explanation: "Fact. The piece calls out latency and complexity from heavy service-to-service traffic." |
|
}, |
|
{ |
|
text: "Kubernetes is commonly used to orchestrate microservices and automate deploy/scale across environments.", |
|
isFact: true, |
|
explanation: "Fact. The article highlights the need for orchestration tools like Kubernetes for distributed services." |
|
}, |
|
{ |
|
text: "Many enterprises still run monoliths effectively, and some use componentized monoliths.", |
|
isFact: true, |
|
explanation: "Fact. It explicitly notes there is no one-size-fits-all; monoliths can remain effective." |
|
}, |
|
{ |
|
text: "Hybrid estates are common: mixing on-prem, PaaS, IaaS, and SaaS with careful integration and governance.", |
|
isFact: true, |
|
explanation: "Fact. It emphasizes modern systems spanning multiple environments that must be integrated thoughtfully." |
|
}, |
|
|
|
|
|
{ |
|
text: "Adopting microservices means you should rewrite everything at once to realize benefits quickly.", |
|
isFact: false, |
|
explanation: "Fiction. The article recommends incremental decomposition; not everything needs a rewrite." |
|
}, |
|
{ |
|
text: "If you use microservices, you can ignore monitoring, logging, and tracing because services are small.", |
|
isFact: false, |
|
explanation: "Fiction. Robust observability is even more important due to distributed 'network noise.'" |
|
}, |
|
{ |
|
text: "Copying another company’s architecture is a reliable path to success during transformation.", |
|
isFact: false, |
|
explanation: "Fiction. The guidance is to align with your own business goals; copying rarely succeeds." |
|
}, |
|
{ |
|
text: "Serverless replaces containers entirely; you should avoid combining them in the same system.", |
|
isFact: false, |
|
explanation: "Fiction. The article says serverless often complements microservices/containers." |
|
}, |
|
{ |
|
text: "Security risks disappear once you move from monoliths to containers or microservices.", |
|
isFact: false, |
|
explanation: "Fiction. Breaches can expose sensitive data in any model; runtime security and patching are required." |
|
}, |
|
{ |
|
text: "Microservices automatically reduce costs regardless of team maturity or tooling.", |
|
isFact: false, |
|
explanation: "Fiction. Without strong DevOps, governance, and tooling, microservices can increase overhead." |
|
}, |
|
{ |
|
text: "There is one correct development model: microservices are always the best choice.", |
|
isFact: false, |
|
explanation: "Fiction. The article stresses context: monoliths, SOA, microservices, and serverless each have a place." |
|
} |
|
]; |
|
|
|
let currentIndex = 0, score = 0, answered = false; |
|
|
|
function shuffle(arr) { |
|
for (let i = arr.length - 1; i > 0; i--) { |
|
const j = Math.floor(Math.random() * (i + 1)); |
|
[arr[i], arr[j]] = [arr[j], arr[i]]; |
|
} |
|
} |
|
|
|
function startGame() { |
|
shuffle(statements); |
|
currentIndex = 0; score = 0; answered = false; |
|
document.getElementById('restart-btn').style.display = 'none'; |
|
loadStatement(); updateScore(); |
|
} |
|
|
|
function loadStatement() { |
|
if (currentIndex >= statements.length) return endGame(); |
|
const s = statements[currentIndex]; |
|
document.getElementById('statement').textContent = s.text; |
|
const resultEl = document.getElementById('result'); |
|
resultEl.style.display = 'none'; |
|
resultEl.textContent = ''; |
|
resultEl.className = ''; |
|
document.getElementById('explanation').style.display = 'none'; |
|
document.getElementById('next-btn').style.display = 'none'; |
|
answered = false; updateProgress(); |
|
} |
|
|
|
function guess(isFactGuess) { |
|
if (answered) return; |
|
answered = true; |
|
const correct = statements[currentIndex].isFact; |
|
const resultEl = document.getElementById('result'); |
|
if (isFactGuess === correct) { |
|
resultEl.textContent = 'Correct!'; |
|
resultEl.className = 'correct'; |
|
score++; |
|
} else { |
|
resultEl.textContent = 'Incorrect!'; |
|
resultEl.className = 'incorrect'; |
|
} |
|
resultEl.style.display = 'block'; |
|
const expEl = document.getElementById('explanation'); |
|
expEl.textContent = statements[currentIndex].explanation + " (See source link above.)"; |
|
expEl.style.display = 'block'; |
|
document.getElementById('next-btn').style.display = 'inline-block'; |
|
updateScore(); |
|
} |
|
|
|
function nextStatement() { |
|
currentIndex++; |
|
if (currentIndex < statements.length) loadStatement(); |
|
else endGame(); |
|
} |
|
|
|
function updateScore() { |
|
document.getElementById('score').textContent = `Score: ${score} / ${statements.length}`; |
|
} |
|
|
|
function updateProgress() { |
|
const pct = Math.round((currentIndex / statements.length) * 100); |
|
document.getElementById('progress-bar').style.width = pct + '%'; |
|
} |
|
|
|
function endGame() { |
|
const pct = Math.round((score / statements.length) * 100); |
|
document.getElementById('statement').textContent = |
|
`Game Over! You scored ${score} of ${statements.length} (${pct}%).`; |
|
document.getElementById('result').style.display = 'none'; |
|
document.getElementById('explanation').style.display = 'none'; |
|
document.getElementById('next-btn').style.display = 'none'; |
|
document.getElementById('restart-btn').style.display = 'inline-block'; |
|
document.getElementById('progress-bar').style.width = '100%'; |
|
} |
|
|
|
startGame(); |
|
</script> |
|
</body> |
|
</html> |
|
|