Flask dan Django dirancang di era aplikasi web yang menyajikan HTML. FastAPI lahir untuk pola yang berbeda: backend yang berbicara JSON — dibaca oleh aplikasi mobile, frontend JavaScript, atau layanan lain. Dibangun di atas ASGI (chapter Pengenalan WSGI dan ASGI), FastAPI mengubah type hints menjadi validasi data dan dokumentasi otomatis; seluruh contoh pada chapter ini diuji pada FastAPI 0.128 dengan uvicorn 0.44. Chapter ini hanya pengenalan; pembahasan mendalam dari desain REST sampai autentikasi berlangsung di Section API Development.

Aplikasi FastAPI Pertama #

Struktur dasarnya sekeluarga dengan Flask — decorator mendaftarkan rute, nilai kembalian dikirim ke client. Simpan sebagai main.py:

python
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel

app = FastAPI()


@app.get("/halo")
def halo():
    return {"pesan": "Halo, FastAPI!"}


@app.get("/produk/{produk_id}")
def detail_produk(produk_id: int):
    return {"produk_id": produk_id, "nama": "Buku Python"}


@app.get("/pencarian")
def pencarian(q: str = "", batas: int = 10):
    return {"kata_kunci": q, "batas": batas}


class ProdukResponse(BaseModel):
    nama: str
    harga: int


@app.get("/produk-1", response_model=ProdukResponse)
def produk_satu():
    return {"nama": "Buku Python", "harga": 95000, "catatan_internal": "rahasia"}

Mari kita telaah perbedaan pentingnya dibanding Flask:

  1. Baris 14 (produk_id: int): annotation pada path parameter inilah seluruh “sihir” FastAPI — type hints dibaca saat startup, lalu dipakai memvalidasi setiap request.
  2. Baris 19 (q: str = ""): parameter fungsi dengan nilai default otomatis menjadi query parameter; tanpa default, parameter wajib dikirim client.
  3. Baris 23 (class ProdukResponse(BaseModel)): skema response dideklarasikan sebagai class Pydantic — type hints sekali lagi jadi sumber kebenaran.
  4. Baris 28 (response_model=ProdukResponse): response difilter mengikuti skema; field di luar skema dibuang.

Menguji dengan TestClient #

FastAPI menyediakan TestClient berbasis httpx yang bekerja tanpa menjalankan server:

python
client = TestClient(app)

r = client.get("/halo")
print(r.status_code, r.json())

r = client.get("/produk/7")
print(r.status_code, r.json())
r = client.get("/produk/tujuh")
print(r.status_code, r.json())

print(client.get("/pencarian?q=flask&batas=5").json())
print(client.get("/pencarian").json())

print(client.get("/produk-1").json())

r = client.get("/openapi.json")
print(r.status_code, sorted(r.json()["paths"]))

Output yang Dihasilkan:

text
200 {'pesan': 'Halo, FastAPI!'}
200 {'produk_id': 7, 'nama': 'Buku Python'}
422 {'detail': [{'type': 'int_parsing', 'loc': ['path', 'produk_id'], 'msg': 'Input should be a valid integer, unable to parse string as an integer', 'input': 'tujuh'}]}
{'kata_kunci': 'flask', 'batas': 5}
{'kata_kunci': '', 'batas': 10}
{'nama': 'Buku Python', 'harga': 95000}
200 ['/halo', '/pencarian', '/produk-1', '/produk/{produk_id}']

Baris ketiga adalah momen khas FastAPI: tujuh gagal dikonversi ke int, dan framework menolak request dengan status 422 beserta struktur error lengkap — tipe galat, lokasi, pesan, hingga input yang ditolak. Kita tidak menulis satu baris validasi pun. Di Flask, konversi seperti ini ditangani converter <int:...> yang menghasilkan 404; FastAPI memilih 422 karena masalahnya ada pada isi request, bukan URL yang tidak dikenal.

Baris keenam memperlihatkan response_model bekerja: field catatan_internal tidak pernah sampai ke client.

Validasi dan Skema: Warisan Type Hints #

Seluruh perilaku di atas berdiri di atas type hints yang kita pelajari di Section Type Hints dan Static Analysis — kali ini bukan untuk mypy, melainkan untuk runtime. FastAPI membaca annotation lewat library Pydantic: setiap request masik di-parse, divalidasi, dan dikonversi ke tipe yang dideklarasikan sebelum fungsi rute dijalankan. Kesalahan tipe ditolak lebih awal, sehingga isi fungsi rute selalu bekerja dengan data yang bersih.

Dokumentasi Otomatis #

Baris terakhir output — sorted(r.json()["paths"]) — memperlihatkan daftar seluruh rute pada skema OpenAPI yang FastAPI terbitkan otomatis di /openapi.json. Dari skema itu, FastAPI juga menyajikan dua halaman siap pakai: /docs (Swagger UI) untuk mencoba API langsung dari browser, dan /redoc untuk dokumentasi rapi. Pada Flask maupun Django, dokumentasi interaktif semacam ini menuntut tool tambahan; di FastAPI, gratis sejak baris pertama.

Untuk menjalankan aplikasi sungguhan, gunakan server ASGI — perintahnya uvicorn main:app --reload saat pengembangan, persis pola server uvicorn yang sudah kita jalankan pada chapter Pengenalan WSGI dan ASGI. Untuk request body, autentikasi, dan pola REST yang lengkap, kita lanjutkan di Section API Development.