Beberapa bulan lalu saya bikin REST API pakai Flask untuk sebuah proyek kantor. Performanya lumayan, tapi setelah traffic naik, response time mulai melambat. Saya penasaran coba FastAPI karena banyak yang bilang framework ini "secepat kilat." Ternyata bukan sekadar hype - setelah migrasi, endpoint yang tadinya response 300ms turun ke 40ms. Saya mau share pengalaman migrasi dan tutorial dasar FastAPI dari nol sampai API production-ready.
Kalau kamu sudah pernah pakai Flask atau Django, belajar FastAPI bakal terasa familiar. Tapi yang bikin beda: FastAPI pakai Python type hints untuk validasi otomatis, generate dokumentasi API secara real-time, dan jalan di atas Starlette + Pydantic yang memang dirancang untuk performa tinggi. Dibanding Flask, FastAPI bisa 2-3x lebih cepat dalam benchmark standar.
Apa Itu FastAPI dan Kenapa Harus Pakai?
FastAPI adalah modern web framework untuk Python yang dibuat oleh Sebastin Ramrez. Framework ini menggunakan Python 3.6+ type hints sebagai pondasi utama. Artinya, setiap parameter yang kamu definisikan di endpoint langsung divalidasi secara otomatis tanpa perlu nulis kode validasi manual.
Beberapa keunggulan utama FastAPI yang saya rasakan langsung:
- Performa tinggi: Setara dengan Node.js dan Go. Berdasarkan benchmark pihak ketiga, FastAPI adalah salah satu framework Python tercepat yang tersedia.
- Type hints = validasi otomatis: Kalau kamu minta parameter
age: intdan user kirim string, FastAPI langsung return error 422 dengan pesan jelas. Kamu nggak perlu nulisif not isinstance(age, int)manual. - Dokumentasi otomatis: Swagger UI dan ReDoc tersedia gratis di
/docsdan/redoc. Tim frontend langsung bisa coba API tanpa nunggu dokumentasi manual. - Async support native: Dukungan
async/awaitbuilt-in, cocok untuk API yang call service lain (database, external API, Redis, dll). - Dependency injection: Sistem DI yang clean tanpa library tambahan. Berguna banget untuk manage koneksi database, autentikasi, dan konfigurasi.
Instalasi dan Setup Proyek
Pertama, pastikan Python 3.8+ sudah terinstall. Saya rekomendasi pakai venv atau uv untuk isolasi environment. Kalau kamu belum kenal uv, itu package manager Python modern yang jauh lebih cepat dari pip - worth banget buat dicoba.
# Buat virtual environment
python3 -m venv venv
source venv/bin/activate
# Install FastAPI dan uvicorn (ASGI server)
pip install fastapi uvicorn[standard]
# Optional: install untuk database
pip install sqlalchemy asyncpg
Buat file main.py dan tulis kode pertama kamu:
from fastapi import FastAPI
app = FastAPI(
title="API Produk",
description="REST API untuk manajemen produk",
version="1.0.0"
)
@app.get("/")
async def root():
return {"message": "Halo! API sudah jalan."}
Jalankan server development:
uvicorn main:app --reload --host 0.0.0.0 --port 8000
Buka browser ke http://localhost:8000/docs dan kamu akan lihat Swagger UI yang udah auto-generated. Coba juga http://localhost:8000/redoc untuk tampilan dokumentasi alternatif yang lebih clean.
Membuat CRUD API dengan Pydantic Models
Mari kita bikin API untuk manage produk. Pertama, define Pydantic model untuk validasi input dan output. Pydantic ini jantungnya FastAPI - setiap data yang masuk dan keluar divalidasi berdasarkan schema yang kamu definisikan.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import Optional
from datetime import datetime
app = FastAPI(title="API Produk", version="1.0.0")
# Pydantic model untuk input
class ProductCreate(BaseModel):
name: str = Field(..., min_length=2, max_length=100)
price: float = Field(..., gt=0)
stock: int = Field(..., ge=0)
description: Optional[str] = None
# Pydantic model untuk response
class ProductResponse(BaseModel):
id: int
name: str
price: float
stock: int
description: Optional[str]
created_at: datetime
# Simulasi database (di production pakai PostgreSQL/MySQL)
products_db: dict[int, dict] = {}
next_id = 1
@app.post("/products", response_model=ProductResponse, status_code=201)
async def create_product(product: ProductCreate):
global next_id
new_product = {
"id": next_id,
"name": product.name,
"price": product.price,
"stock": product.stock,
"description": product.description,
"created_at": datetime.now()
}
products_db[next_id] = new_product
next_id += 1
return new_product
@app.get("/products", response_model=list[ProductResponse])
async def list_products(skip: int = 0, limit: int = 10):
return list(products_db.values())[skip:skip + limit]
@app.get("/products/{product_id}", response_model=ProductResponse)
async def get_product(product_id: int):
if product_id not in products_db:
raise HTTPException(status_code=404, detail="Produk tidak ditemukan")
return products_db[product_id]
@app.put("/products/{product_id}", response_model=ProductResponse)
async def update_product(product_id: int, product: ProductCreate):
if product_id not in products_db:
raise HTTPException(status_code=404, detail="Produk tidak ditemukan")
products_db[product_id].update({
"name": product.name,
"price": product.price,
"stock": product.stock,
"description": product.description
})
return products_db[product_id]
@app.delete("/products/{product_id}", status_code=204)
async def delete_product(product_id: int):
if product_id not in products_db:
raise HTTPException(status_code=404, detail="Produk tidak ditemukan")
del products_db[product_id]
Perhatikan beberapa hal penting di kode di atas:
Field(..., gt=0)- harga harus lebih besar dari 0. Kalau user kirim harga negatif, FastAPI otomatis reject dengan error message yang jelas.response_model- output difilter sesuai model. Field yang nggak ada di model response nggak akan ikut kekirim, walau ada di data asli.HTTPException- cara standar untuk return error HTTP dengan status code dan pesan custom.- Pagination - parameter
skipdanlimitpunya default value, jadi user nggak harus specify keduanya.
Validasi Otomatis yang Bikin Hidup Lebih Mudah
Salah satu fitur yang bikin saya jatuh cinta sama FastAPI adalah validasi otomatis. Coba kirim request dengan data yang salah:
# Harga negatif - akan ditolak otomatis
curl -X POST http://localhost:8000/products \
-H "Content-Type: application/json" \
-d '{"name": "Laptop", "price": -100, "stock": 5}'
# Response error 422:
# {
# "detail": [{
# "type": "greater_than",
# "loc": ["body", "price"],
# "msg": "Input should be greater than 0",
# "input": -100
# }]
# }
Kamu nggak perlu nulis kode validasi manual sama sekali. Pydantic ngecek tipe data, range, length, format email, URL, dan banyak lagi. Ini ngehemat waktu development yang biasanya habis buat nulis if-else validasi di setiap endpoint.
Dependency Injection untuk Autentikasi
FastAPI punya sistem dependency injection (DI) yang elegant. Kamu bisa inject database session, user yang terautentikasi, atau konfigurasi apa pun tanpa library tambahan. Ini contoh sederhana untuk API key authentication:
from fastapi import Depends, Header, HTTPException
API_KEYS = {
"key-abc123": "admin",
"key-def456": "read_only"
}
async def verify_api_key(x_api_key: str = Header(...)):
if x_api_key not in API_KEYS:
raise HTTPException(status_code=403, detail="API key tidak valid")
return {"role": API_KEYS[x_api_key]}
@app.get("/secure-data")
async def secure_data(user: dict = Depends(verify_api_key)):
return {"message": f"Halo {user['role']}!", "data": "ini data rahasia"}
Setiap endpoint yang butuh autentikasi tinggal tambahin Depends(verify_api_key) di parameter. FastAPI otomatis eksekusi fungsi dependency sebelum endpoint utama. Kalau dependency raise HTTPException, request langsung dihentikan. Clean banget kan?
Tips Optimasi Performa untuk Production
Setelah migrate beberapa proyek ke FastAPI, ini tips yang saya pelajari untuk performa maksimal:
- Gunakan async untuk I/O operations: Kalau endpoint kamu query database atau call API lain, pakai async driver (asyncpg untuk PostgreSQL, aiomysql untuk MySQL). Hindari
defsinkron untuk operasi I/O karena akan blocking. - Connection pooling: Jangan buka koneksi database per request. Pakai
asyncpg.create_pool()atau SQLAlchemy async session dengan pool. - Cache dengan Redis: Endpoint yang return data jarang berubah? Cache hasilnya di Redis. FastAPI cocok banget dipadukan dengan
redis.asyncio. - Gunakan Gunicorn + Uvicorn workers: Untuk production, jalankan dengan multiple workers:
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker. Setiap worker handle request secara paralel. - Response model filtering: Selalu specify
response_modeldi endpoint. Ini nggak cuma untuk dokumentasi, tapi juga nge-filter field yang nggak perlu dikirim, mengurangi response size.
# Production command dengan Gunicorn + multiple workers
gunicorn main:app \
-w 4 \
-k uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:8000 \
--timeout 120 \
--keep-alive 5
Deployment dengan Docker
Untuk deployment yang konsisten, Docker adalah pilihan terbaik. Bikin Dockerfile sederhana:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
# Build dan run
docker build -t my-fastapi-app .
docker run -p 8000:8000 my-fastapi-app
Kalau kamu butuh auto-reload di development tapi stability di production, bisa pakai Docker Compose dengan environment variables untuk switch mode.
FastAPI vs Flask vs Django REST Framework
Buat kamu yang masih ragu milih framework, ini perbandingan singkat berdasarkan pengalaman saya pakai ketiganya:
- FastAPI: Paling cepat, validasi otomatis, async native. Cocok untuk microservice, API yang butuh performa tinggi, atau proyek baru. Learning curve lumayan gentle kalau sudah familiar dengan type hints.
- Flask: Paling fleksibel, ecosystem matang. Cocok untuk prototyping cepat atau proyek kecil. Tapi validasi manual dan nggak ada async native (perlu extension).
- Django REST Framework: Paling feature-complete, admin panel built-in, ORM powerful. Cocok untuk monolith besar. Tapi lebih berat dan performa di bawah FastAPI.
Untuk proyek API-only yang butuh speed, saya pribadi pilih FastAPI. Untuk proyek yang butuh admin panel lengkap dan ORM, Django REST Framework masih juara.
Kesimpulan
FastAPI benar-benar mengubah cara saya nulis API di Python. Validasi otomatis dari type hints nggak cuma ngehemat waktu, tapi juga nge reduce bug yang biasanya muncul dari data yang nggak terduga. Dokumentasi Swagger yang auto-generated bikin tim frontend senang karena bisa langsung coba endpoint tanpa nunggu wiki atau Postman collection.
Kalau kamu lagi cari framework untuk proyek API baru, coba FastAPI. Setup-nya cepat, performanya kencang, dan dokumentasinya lengkap. Migrasi dari Flask juga relatif straightforward karena konsepnya mirip - route decorator, request/response handling, dll.
Sudah pernah coba FastAPI? Atau masih setia sama Flask/Django? Share pengalaman kamu di kolom komentar, saya penasaran framework Python mana yang paling populer di kalangan developer Indonesia.