Setelah memahami siklus request-response, saatnya menulis aplikasi web sungguhan. Kita mulai dari Flask, framework Python yang paling sering dipilih untuk belajar karena ukurannya kecil dan tidak memaksakan struktur tertentu. Flask menyebut dirinya microframework: intinya hanya menyediakan routing dan pengolahan request, sedangkan database, form, dan autentikasi ditambahkan lewat extension terpisah. Pada chapter ini kita akan membuat aplikasi Flask pertama (diuji pada Flask 3.1.3) dan mengujinya tanpa browser sama sekali.

Aplikasi Flask Pertama #

Aplikasi Flask sesungguhnya bisa dibangun dalam satu berkas. Simpan kode berikut sebagai app.py:

python
from flask import Flask

app = Flask(__name__)


@app.route("/")
def beranda():
    return "Halo, ini beranda!"


@app.route("/tentang")
def tentang():
    return "<h1>Tentang Kami</h1><p>Situs belajar Python.</p>"


@app.route("/api/pengumuman")
def pengumuman():
    return {"status": "ok", "jumlah_pesan": 3}

Mari kita telaah baris per baris:

  1. Baris 3 (app = Flask(__name__)): object app menjadi pusat aplikasi; argument __name__ membantu Flask menemukan lokasi templates dan static files.
  2. Baris 6 (@app.route("/")): decorator (materi chapter Function Decorators) mendaftarkan fungsi beranda sebagai penangani URL /. Inilah mekanisme routing yang pada chapter sebelumnya masih kita tulis manual.
  3. Baris 8 (return "Halo, ini beranda!"): nilai kembalian menjadi body response dengan status 200 secara otomatis.
  4. Baris 18 (return {"status": "ok", ...}): dictionary otomatis diserialisasi menjadi JSON dengan header Content-Type: application/json.

Menguji Tanpa Browser #

Flask menyediakan app.test_client() — object yang meniru browser dan mengirim request sungguhan ke aplikasi kita tanpa membuka port jaringan. Pola ini juga yang dipakai pytest saat menguji aplikasi web (materi Section Testing dan Code Quality):

python
client = app.test_client()

r1 = client.get("/")
print("r1.status_code =", r1.status_code)
print("r1.text =", r1.text)

r2 = client.get("/tentang")
print("r2.content_type =", r2.content_type)
print("r2.text =", r2.text)

r3 = client.get("/api/pengumuman")
print("r3.status_code =", r3.status_code)
print("r3.get_json() =", r3.get_json())

r4 = client.get("/halaman-tidak-ada")
print("r4.status_code =", r4.status_code)

Output yang Dihasilkan:

text
r1.status_code = 200
r1.text = Halo, ini beranda!
r2.content_type = text/html; charset=utf-8
r2.text = <h1>Tentang Kami</h1><p>Situs belajar Python.</p>
r3.status_code = 200
r3.get_json() = {'jumlah_pesan': 3, 'status': 'ok'}
r4.status_code = 404

Empat baris pertama memperlihatkan perilaku penting Flask: string dikirim sebagai HTML (header text/html), sementara dictionary dikirim sebagai JSON dan bisa dibaca kembali dengan r3.get_json(). Baris terakhir menegaskan bahwa URL yang tidak terdaftar menghasilkan status 404.

Server Pengembangan dan Daftar Route #

Untuk menjalankan aplikasi di komputer sendiri, tambahkan blok berikut di akhir app.py, lalu eksekusi berkas tersebut:

python
if __name__ == "__main__":
    app.run(debug=True)

Flask akan memulai server pengembangan (Werkzeug) di alamat http://127.0.0.1:5000. Mode debug=True mengaktifkan dua hal: reloader yang memuat ulang kode setiap berkas disimpan, dan halaman error detail lengkap dengan traceback saat terjadi exception.

Flask juga memiliki CLI untuk memeriksa route yang terdaftar tanpa membuka aplikasi:

bash
python3 -m flask --app app.py routes

Output yang Dihasilkan:

text
Endpoint    Methods  Rule                   
----------  -------  -----------------------
beranda     GET      /                      
pengumuman  GET      /api/pengumuman        
static      GET      /static/<path:filename>
tentang     GET      /tentang               

Rute static terdaftar otomatis oleh Flask — kita belum menulisnya sama sekali. Endpoint bernama static inilah yang melayani berkas CSS, JavaScript, dan gambar, yang akan kita bahas pada chapter Templates dan Static Files.

Struktur Proyek Kecil #

Aplikasi satu berkas cukup untuk belajar. Begitu jumlah halaman bertambah, konvensi Flask adalah memisahkan templates dan static files ke direktori tersendiri:

text
toko-buku/
├── app.py
├── templates/
│   ├── base.html
│   ├── beranda.html
│   └── produk/
│       └── detail.html
└── static/
    ├── css/
    │   └── style.css
    └── js/
        └── app.js

Flask mencari templates di folder templates/ dan berkas publik di static/ secara otomatis, relatif terhadap lokasi app.py. Untuk aplikasi yang lebih besar, kode biasanya dipecah dengan blueprint — pola pengelompokan route per fitur yang menjaga aplikasi tetap rapi tanpa meninggalkan kesederhanaan Flask.