Flask adalah micro web framework untuk Python yang ringan, fleksibel, dan mudah dipelajari. Tidak seperti Django yang hadir dengan segudang fitur bawaan, Flask memberi kamu kebebasan penuh untuk memilih komponen yang kamu butuhkan. Di tutorial ini, kita akan membangun aplikasi web sederhana secara bertahap — dari Hello World, routing, template, form, hingga REST API dan testing — sehingga kamu punya fondasi kuat untuk membangun proyek nyata.
Kenapa Flask? Kelebihan dan Kapan Menggunakannya
Flask punya kurva belajar yang landai karena intinya hanya beberapa file. Kamu cocok memakai Flask ketika: membangun API kecil atau layanan microservice, membuat prototipe dengan cepat, atau belajar konsep web development tanpa kerumitan. Untuk proyek besar dengan ORM, autentikasi, dan admin panel bawaan, Django mungkin lebih pas. Sementara itu, jika kamu butuh API modern dengan validasi otomatis dan dokumentasi interaktif, coba FastAPI.
Menyiapkan Lingkungan Proyek
Mulailah dengan membuat virtual environment agar dependensi proyek terisolasi. Kamu bisa pakai venv bawaan Python, atau kalau ingin lebih cepat, uv, package manager super cepat pengganti pip. Berikut langkahnya dengan venv standar:
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install flask
Aplikasi Pertama: Hello World
Buat file app.py dengan isi berikut:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Hello, BengkelKode!"
if __name__ == "__main__":
app.run(debug=True)
Jalankan dengan python app.py, lalu buka http://127.0.0.1:5000 di browser. Kamu akan melihat teks Hello, BengkelKode!. Decorator @app.route("/") menghubungkan URL / dengan fungsi home(), dan debug=True memuat ulang server otomatis setiap kali kamu mengubah kode.
Tips: Mode debug sangat membantu saat development, tapi jangan pernah menyalakannya di production karena bisa membocorkan kode dan memungkinkan eksekusi kode arbitrer.
Routing dan Dynamic Routes
Routing menentukan fungsi mana yang menangani URL tertentu. Kamu juga bisa membuat dynamic route untuk menangkap bagian dari URL sebagai variabel:
@app.route("/")
def home():
return "Selamat datang!"
@app.route("/artikel/<int:article_id>")
def show_article(article_id):
return f"Menampilkan artikel #{article_id}"
@app.route("/user/<username>")
def show_user(username):
return f"Halo, {username}!"
Dengan <int:article_id>, Flask otomatis mengonversi bagian URL menjadi integer. Jika kamu menulis <username> tanpa tipe, nilainya berupa string.
Template dengan Jinja2
Mengembalikan string biasa tidak cukup untuk halaman HTML yang rapi. Flask menggunakan mesin template Jinja2. Buat folder templates/ dan file index.html:
<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>Daftar Artikel</h1>
<ul>
{% for article in articles %}
<li>{{ article }}</li>
{% endfor %}
</ul>
</body>
</html>
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home():
articles = ["Belajar Flask", "Belajar FastAPI", "Belajar Django"]
return render_template("index.html", title="BengkelKode", articles=articles)
render_template() menggabungkan template dengan data yang kamu kirim. Sintaks {{ }} dipakai untuk menampilkan nilai, dan {% %} untuk logika seperti perulangan.
Menerima Input dari Formulir (GET & POST)
Hampir semua aplikasi web butuh menerima input pengguna. Berikut contoh form sederhana dengan metode POST:
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route("/", methods=["GET", "POST"])
def home():
name = None
if request.method == "POST":
name = request.form.get("name", "").strip()
return render_template("index.html", name=name)
<form method="post">
<input type="text" name="name" placeholder="Namamu">
<button type="submit">Kirim</button>
</form>
{% if name %}
<p>Halo, {{ name }}! Selamat datang di BengkelKode.</p>
{% endif %}
Objek request menyimpan data permintaan. Untuk form POST gunakan request.form, sedangkan untuk query string (?q=...) gunakan request.args.get("q").
Menyimpan Data dengan SQLite
Untuk menyimpan data secara permanen, kita pakai SQLite karena tidak butuh server eksternal. Python sudah punya modul sqlite3 bawaan — kalau kamu ingin mendalaminya, baca tutorial SQLite dengan Python.
import sqlite3
from flask import Flask, g, render_template, request
app = Flask(__name__)
DATABASE = "app.db"
def get_db():
if "db" not in g:
g.db = sqlite3.connect(DATABASE)
g.db.row_factory = sqlite3.Row
return g.db
@app.teardown_appcontext
def close_db(exception=None):
db = g.pop("db", None)
if db is not None:
db.close()
def init_db():
with app.app_context():
db = get_db()
db.execute(
"CREATE TABLE IF NOT EXISTS artikel (id INTEGER PRIMARY KEY, judul TEXT)"
)
db.commit()
@app.route("/", methods=["GET", "POST"])
def home():
db = get_db()
if request.method == "POST":
judul = request.form.get("judul", "").strip()
if judul:
db.execute("INSERT INTO artikel (judul) VALUES (?)", (judul,))
db.commit()
artikel = db.execute("SELECT * FROM artikel ORDER BY id DESC").fetchall()
return render_template("index.html", artikel=artikel)
Kita pakai objek g untuk menyimpan koneksi per-request, lalu menutupnya otomatis lewat teardown_appcontext. Parameter ? pada query berfungsi mencegah serangan SQL injection.
<form method="post">
<input type="text" name="judul" placeholder="Judul artikel baru">
<button type="submit">Simpan</button>
</form>
<ul>
{% for a in artikel %}
<li>{{ a["judul"] }}</li>
{% endfor %}
</ul>
Peringatan: Selalu gunakan parameterized query (tanda ?) alih-alih menyusun string SQL secara manual. Menyambung input pengguna langsung ke query akan membuka celah SQL injection.
Membuat Endpoint REST API JSON
Flask juga cocok untuk membuat API. Jika kamu belum paham konsepnya, baca dulu apa itu REST API dan bagaimana cara kerjanya. Berikut endpoint yang mengembalikan JSON:
from flask import Flask, jsonify
app = Flask(__name__)
artikel = [
{"id": 1, "judul": "Belajar Flask"},
{"id": 2, "judul": "Belajar FastAPI"},
]
@app.route("/api/artikel")
def api_artikel():
return jsonify(artikel)
@app.route("/api/artikel/<int:article_id>")
def api_artikel_detail(article_id):
item = next((a for a in artikel if a["id"] == article_id), None)
if item is None:
return jsonify({"error": "Tidak ditemukan"}), 404
return jsonify(item)
Fungsi jsonify() mengubah dict/list Python menjadi response JSON dengan header Content-Type: application/json yang benar. Untuk API yang lebih besar dengan validasi otomatis, pertimbangkan FastAPI.
Testing dengan Pytest
Supaya aplikasi kita andal, tulis pengujian otomatis. Flask punya test client bawaan yang bisa dipanggil lewat Pytest:
# test_app.py
import pytest
from app import app
@pytest.fixture
def client():
app.config["TESTING"] = True
with app.test_client() as client:
yield client
def test_home(client):
resp = client.get("/")
assert resp.status_code == 200
def test_api_artikel(client):
resp = client.get("/api/artikel")
assert resp.status_code == 200
assert resp.get_json()[0]["judul"] == "Belajar Flask"
def test_api_not_found(client):
resp = client.get("/api/artikel/999")
assert resp.status_code == 404
pip install pytest
pytest -v
Dengan app.test_client(), kamu bisa mengirim request ke aplikasi tanpa menjalankan server sungguhan, sehingga pengujian berjalan cepat dan stabil.
Menjalankan di Production
Server bawaan Flask (app.run()) hanya untuk development. Di production, gunakan WSGI server seperti Gunicorn:
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:app
Parameter -w 4 menjalankan 4 worker process. Jangan lupa set debug=False dan gunakan environment variable untuk konfigurasi rahasia seperti SECRET_KEY.
Kesimpulan
Kamu sudah membangun aplikasi web Flask lengkap: routing, template, form, database, REST API, dan testing. Flask memberi fondasi yang ringan dan mudah dipahami — ideal untuk belajar konsep web development maupun membangun API kecil. Langkah selanjutnya, coba tambahkan autentikasi pengguna, integrasi dengan database yang lebih besar, atau deploy ke server menggunakan Docker.
Apakah Flask cocok untuk proyek besar?
Flask bisa dipakai untuk proyek besar, tetapi kamu harus merakit sendiri banyak komponen (ORM, autentikasi, dsb.) yang di Django sudah tersedia bawaan. Untuk tim besar yang butuh konvensi dan fitur lengkap, Django sering lebih cocok.
Apa bedanya Flask dengan FastAPI?
Flask lebih sederhana dan sinkron, sedangkan FastAPI dibangun khusus untuk API modern dengan dukungan async, validasi otomatis via Pydantic, dan dokumentasi interaktif. Pelajari selengkapnya di tutorial FastAPI.
Apakah saya perlu memahami Python dulu sebelum belajar Flask?
Ya, sebaiknya kamu paham dasar Python seperti variabel, fungsi, dan modul. Kalau belum, mulai dari cara install Python dan menulis program pertamamu.