Belajar FastAPI - Microservices & Async Architecture
Episode 22 of 28

Belajar FastAPI - Microservices & Async Architecture

Memecah monolith menjadi microservices FastAPI: pola service split yang sehat, komunikasi antar service via HTTP internal, event-driven dengan message broker RabbitMQ/Kafka, dan arsitektur async yang menyatukan semuanya.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah 21 episode membangun satu aplikasi FastAPI yang solid, sekarang kita perluas cakrawala: microservices. Aplikasi yang makin besar sering dipecah menjadi beberapa service yang lebih kecil — masing-masing FastAPI, masing-masing dengan tanggung jawab dan database sendiri.

Mengapa episode ini penting? Microservices menambah kompleksitas jaringan — kalian menukar "semua dalam satu proses" dengan "banyak proses yang saling bicara". Tanpa pola komunikasi yang benar, arsitektur ini berubah menjadi benang kusut. Episode ini memberi kalian pola yang terbukti: kapan harus pecah, bagaimana bicara antar service, dan kapan harus memakai event broker.

Kapan Memecah Aplikasi

Microservices bukan jawaban untuk semua masalah. Pola yang sehat biasanya mulai dari monolith modular — satu aplikasi FastAPI dengan router dan folder per domain — lalu memecah saat ada alasan konkret:

Alasan pecahBukan alasan
Tim berbeda perlu deploy sendiri"Kelihatan lebih keren"
Skala berbeda per domainAplikasi baru mulai (skip)
Batas keamanan/kompliansKetakutan pada monolith
100%

Perhatikan perubahan penting: database ikut terpecah. Setiap service memiliki database sendiri — bukan hanya memindahkan kode.

Important

Microservice sejati = satu tim, satu service, satu database. Dua service yang berbagi satu database adalah monolith yang didekorasi. Jika kalian belum siap memecah database, lebih baik tetap satu aplikasi FastAPI dengan struktur modular (router per domain).

Komunikasi Antar Service: HTTP Sync

Cara paling langsung: service A memanggil endpoint service B via HTTP. Di FastAPI, gunakan httpx (bukan requests) agar bisa dipakai dari handler async:

PythonPanggil service lain
import httpx
 
USERS_SERVICE = "http://users-service:8001"
 
 
async def get_user_profile(user_id: int) -> dict:
    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"{USERS_SERVICE}/users/{user_id}"
        )
    response.raise_for_status()
    return response.json()
 
 
@app.get("/orders/{order_id}/customer/")
async def get_order_with_customer(
    order_id: int,
    db: AsyncSession = Depends(get_async_db),
) -> dict:
    order = await db.get(models.Order, order_id)
    customer = await get_user_profile(order.customer_id)
    return {"order": order, "customer": customer}

Poin penting: await client.get(...) — sambil menunggu response service lain, event loop tetap melayani request lain (pola episode 14). Tambahkan timeout dan retry untuk menghadapi service yang sedang naik-turun.

Warning

Jangan pernah memanggil service lain secara sinkron di dalam hot path tanpa fallback. Kalau users-service mati, orders-service ikut gagal — inilah masalah "cascading failure". Selalu beri timeout, retry, dan circuit breaker untuk koneksi HTTP antar service.

Event-Driven: Message Broker

Pola yang lebih tangguh untuk integrasi lintas domain: event-driven. Service mempublikasikan peristiwa ("order.created") ke broker, dan service lain yang peduli mendengarnya. Ini memutus dependensi langsung:

PythonPublish event (aio-pika)
import json
 
import aio_pika
 
RABBITMQ_URL = "amqp://guest:guest@rabbitmq:5672/"
 
 
async def publish_event(routing_key: str, payload: dict) -> None:
    connection = await aio_pika.connect_robust(RABBITMQ_URL)
    async with connection:
        channel = await connection.channel()
        await channel.default_exchange.publish(
            aio_pika.Message(
                body=json.dumps(payload).encode(),
                content_type="application/json",
            ),
            routing_key=routing_key,
        )
 
 
@app.post("/orders/", status_code=201)
async def create_order(order: schemas.OrderCreate) -> dict:
    order_id = 1
    await publish_event(
        "order.created",
        {"order_id": order_id, "customer_id": order.customer_id},
    )
    return {"order_id": order_id}

order.created dipublikasikan ke RabbitMQ, lalu consumer (misal payments-service atau notifications-service) bereaksi — masing-masing berjalan independen.

Tip

Pilih RabbitMQ untuk task queue & routing yang fleksibel (work queue, direct/topic exchange); pilih Kafka untuk streaming event volume tinggi dan replay history. Aturan praktis: mulai dari RabbitMQ, pindah ke Kafka saat butuh retensi dan replay.

Consumer Async dengan FastAPI

Consumer bisa hidup di service yang sama — misalnya FastAPI yang menangani REST dan WebSocket sekaligus men-consume event untuk broadcast realtime (menghubungkan episode 13 dan 22):

PythonConsume event di aplikasi
import asyncio
import json
from contextlib import asynccontextmanager
 
import aio_pika
from fastapi import FastAPI
 
 
async def consume_events() -> None:
    connection = await aio_pika.connect_robust(RABBITMQ_URL)
    async with connection:
        channel = await connection.channel()
        queue = await channel.declare_queue("order.created", durable=True)
        async with queue.iterator() as queue_iter:
            async for message in queue_iter:
                async with message.process():
                    payload = json.loads(message.body)
                    await manager.broadcast(
                        f"order baru: {payload['order_id']}"
                    )
 
 
@asynccontextmanager
async def lifespan(app: FastAPI):
    task = asyncio.create_task(consume_events())
    yield
    task.cancel()
 
 
app = FastAPI(lifespan=lifespan)

lifespan (Starlette) menjalankan consumer saat app start dan membersihkannya saat shutdown — pola modern FastAPI untuk kode yang harus hidup di balik layar.

Pattern Inter-Service: Pilih Sesuai Kebutuhan

PatternKapanTrade-off
HTTP syncData harus ada sekarangCascading failure risk
Async brokerProses bisa ditunda/paralelEventual consistency
gRPCInternal, performa ekstremKompleksitas protobuf
Database sharing❌ itu bukan microservice

Common Pitfalls

PitfallSolusi
Service berbagi databasePecah database per service
HTTP sync tanpa timeout/retryTimeout + retry + circuit breaker
Pecah sebelum modularMulai monolith modular
Event tanpa retryDead-letter queue + retry policy
Konsumer memblokir event loopasync def handler + await semua I/O

Penutup

Inti yang harus dibawa pulang:

  • Mulai dari monolith modular; pecah saat tim/skala/batas benar-benar menuntut.
  • Setiap service punya database sendiri.
  • Komunikasi: HTTP sync untuk data real-time, event broker (RabbitMQ/Kafka) untuk integrasi lintas domain.
  • httpx async + lifespan consumer adalah toolkit dasar service FastAPI.

Di episode 23 selanjutnya kita akan membahas AI/ML integration & streaming — integrasi LLM dengan tool-calling berbasis schema Pydantic, streaming response token-by-token, dan serving model — panggung utama FastAPI di 2026!

Belajar FastAPI - Microservices & Async Architecture | Belajar FastAPI