Framework web dan pengenalan FastAPI

Perbandingan Flask, FastAPI, dan Django serta layanan kecil pertama dengan FastAPI.

Daftar isi

Pustaka HTTP seperti requests menempatkan Python sebagai sisi klien, sedangkan sebagian besar aplikasi nyata juga memerlukan sisi server, yaitu program yang menerima permintaan dan membalasnya. Framework web menyediakan struktur untuk pekerjaan itu, mulai dari penetapan rute (routing), pembacaan masukan, hingga pembuatan respons. Topik ini membandingkan Flask, FastAPI, dan Django secara ringkas, kemudian membangun layanan catatan kecil dengan FastAPI beserta pengujian TestClient-nya. Seluruh contoh diuji tanpa menyalakan server sungguhan, sehingga perilaku layanan dapat diperiksa langsung dari terminal.

Flask, FastAPI, dan Django#

Ketiga framework ini banyak dipakai pada proyek Python, dan ketiganya mampu menghasilkan layanan yang sama, tetapi filosofi serta biaya awal mempelajarinya berbeda. Flask adalah microframework yang menyediakan inti kecil dan membiarkan pilihan lain terbuka. Django membawa paket lengkap, mulai dari ORM (object-relational mapper), autentikasi, hingga panel admin, sehingga paling banyak hal baru untuk dipelajari tetapi paling siap untuk aplikasi penuh. FastAPI berfokus pada API dengan validasi otomatis berbasis type hint dan dokumentasi interaktif yang dibuat sendiri oleh framework.

AspekFlaskFastAPIDjango
Lingkupmicroframework, inti kecilfokus pada APIframework lengkap
Validasi masukanditulis sendiri atau ekstensiotomatis melalui model pydanticmelalui form dan serializer
Dokumentasi APImelalui alat tambahandibuat otomatis (OpenAPI)melalui ekstensi
Cocok untuklayanan kecil hingga menengahAPI dan layanan dataaplikasi web penuh

Pada topik ini, pilihan jatuh pada FastAPI karena validasi dan dokumentasi otomatisnya memperlihatkan alur data dengan jelas, sedangkan Flask dan Django tetap menjadi pilihan yang sah untuk kebutuhan yang berbeda. Perbedaan lingkup ini berdampak langsung pada pekerjaan sehari-hari. Pada Flask, validasi, dokumentasi, dan migrasi basis data berarti memilih ekstensi satu per satu, sedangkan Django menyediakannya dengan konvensi yang telah ditetapkan. FastAPI menempati posisi tengah, yaitu ringan seperti Flask pada struktur berkas, tetapi validasi dan dokumentasinya sudah melekat pada definisi rute. Layanan yang dibangun bernama layanan catatan, yaitu API sederhana untuk menambah dan membaca catatan.

Layanan catatan pertama#

Berkas berikut mendefinisikan satu aplikasi FastAPI dengan tiga rute. Decorator @app.get dan @app.post mendaftarkan fungsi untuk metode HTTP dan jalur tertentu, sehingga decorator inilah yang menghubungkan URL dengan fungsi Python. Parameter nomor pada rute /catatan/{nomor} diberi anotasi int, dan FastAPI menolak permintaan dengan nilai non-angka sebelum fungsi dijalankan. Model CatatanBaru berupa kelas pydantic yang mewajibkan judul berupa string, sedangkan isi diberi nilai default string kosong.

python main.py
"""Layanan catatan kecil dengan FastAPI."""
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()


class CatatanBaru(BaseModel):
    judul: str
    isi: str = ""


catatan: list[dict] = []


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


@app.post("/catatan", status_code=201)
def tambah_catatan(data: CatatanBaru):
    item = {"nomor": len(catatan) + 1, "judul": data.judul, "isi": data.isi}
    catatan.append(item)
    return item


@app.get("/catatan/{nomor}")
def detail_catatan(nomor: int):
    for item in catatan:
        if item["nomor"] == nomor:
            return item
    raise HTTPException(status_code=404, detail="catatan tidak ditemukan")

Ketiga fungsi mengembalikan dictionary, dan FastAPI mengubahnya secara otomatis menjadi JSON beserta header yang sesuai. Rute POST diberi argumen status_code=201 agar respons pembuatan memakai kode yang tepat, sedangkan rute detail menimbulkan HTTPException dengan kode 404 apabila nomor catatan tidak ditemukan. FastAPI merender exception tersebut menjadi respons JSON berisi kunci detail.

Menjalankan layanan dengan uvicorn#

FastAPI hanyalah pustaka aplikasi, sedangkan penerimaan koneksi HTTP dikerjakan server ASGI bernama uvicorn, dengan ASGI (Asynchronous Server Gateway Interface) sebagai antarmuka antara server dan aplikasi Python asinkron. Perintah uvicorn main:app berarti memuat variabel app dari berkas main.py, dan bentuk penamaan berkas:variabel inilah yang dipakai di seluruh dokumentasi FastAPI. Apabila layanan perlu melayani banyak permintaan serentak, fungsi rute dapat ditulis dengan async def tanpa mengubah bentuk rutenya. Perintah berikut menyalakan layanan pada port 8000, dan argumen --reload memuat ulang kode secara otomatis setiap berkas berubah.

bash
# tidak-dijalankan: proses server berjalan terus sehingga tidak dieksekusi di sandbox
# menyalakan layanan FastAPI pada port 8000
uvicorn main:app --reload

Setelah server menyala, permintaan diterima di http://127.0.0.1:8000, dan dokumentasi interaktif yang dihasilkan otomatis tersedia di jalur /docs. Port 8000 adalah nilai default uvicorn, dan argumen --port mengubahnya bila port tersebut sudah dipakai proses lain. Argumen --reload hanya dipakai pada tahap pengembangan, sedangkan penerapan produksi menjalankan uvicorn tanpa opsi tersebut. Menyalakan server sungguhan untuk setiap pengujian berarti mengelola proses, port, dan pembersihannya, sehingga FastAPI menyediakan jalan yang lebih langsung berupa TestClient.

Menguji layanan dengan TestClient#

Berkas uji berikut memanggil aplikasi secara langsung tanpa proses server, karena TestClient mengirim permintaan ke aplikasi di dalam memori yang sama. Klien ini dibangun di atas pustaka httpx dan tidak melewati soket jaringan, sehingga pengujian berjalan cepat dan tidak terpengaruh port yang sedang dipakai proses lain. Objek responsnya menyediakan atribut yang sama dengan respons HTTP biasa, yaitu status_code, headers, dan metode json(), sehingga pernyataan pengujian dapat ditulis tanpa penyesuaian. Rangkaiannya mencakup lima kasus, yaitu rute /halo, pembuatan catatan, pembacaan catatan pertama, catatan yang tidak ada, serta isi permintaan tanpa judul.

python uji_main.py
# tidak-dijalankan: skrip ini dijalankan lewat `python3 uji_main.py` pada blok terminal berikutnya
from fastapi.testclient import TestClient

from main import app

client = TestClient(app)

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

respons = client.post("/catatan", json={"judul": "belajar fastapi", "isi": "hari pertama"})
print(respons.status_code, respons.json())

respons = client.get("/catatan/1")
print(respons.status_code, respons.json())

respons = client.get("/catatan/99")
print(respons.status_code, respons.json())

respons = client.post("/catatan", json={"isi": "tanpa judul"})
print(respons.status_code)

Blok terminal berikut menjalankan berkas tersebut dari direktori tempat main.py berada, sehingga pernyataan from main import app menemukan modul main.

bash
# menguji layanan FastAPI tanpa menyalakan server
python3 uji_main.py
text Keluaran
200 {'pesan': 'Halo dari FastAPI'}
201 {'nomor': 1, 'judul': 'belajar fastapi', 'isi': 'hari pertama'}
200 {'nomor': 1, 'judul': 'belajar fastapi', 'isi': 'hari pertama'}
404 {'detail': 'catatan tidak ditemukan'}
422

Empat kasus pertama berjalan sesuai rancangan, yaitu 200 untuk /halo, 201 untuk pembuatan catatan, 200 untuk pembacaan, dan 404 dengan kunci detail untuk catatan yang tidak ada. Kasus terakhir menarik karena FastAPI membalas 422 tanpa pernah menjalankan fungsi tambah_catatan, dan kode status 422 menyatakan bahwa isi permintaan gagal divalidasi. Validasi ini bekerja karena parameter data diberi tipe CatatanBaru, dan inilah manfaat utama integrasi pydantic pada FastAPI.

Ringkasan#

  • Flask, Django, dan FastAPI menyelesaikan pekerjaan yang sama dengan lingkup berbeda, yaitu inti kecil, paket lengkap, dan fokus pada API dengan validasi otomatis.
  • Rute FastAPI didefinisikan lewat decorator @app.get dan @app.post, dengan parameter jalur dan model pydantic yang divalidasi sebelum fungsi dijalankan.
  • Server ASGI bernama uvicorn menerima koneksi HTTP untuk aplikasi FastAPI, sedangkan TestClient menguji aplikasi di dalam memori tanpa proses server.
  • Kode 422 muncul ketika isi permintaan gagal divalidasi model, sehingga fungsi rute hanya dijalankan untuk data yang sah.

Referensi#