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:

bash
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:

python
@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:

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>
python
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:

python
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)
html
<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.

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.

html
<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:

python
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:

python
# 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
bash
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:

bash
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.