Belajar Flask - Routing, URL & HTTP Methods
Episode 4 of 27

Belajar Flask - Routing, URL & HTTP Methods

Menguasai @app.route untuk memetakan URL ke view function, menangkap variabel path dengan converters int/path/uuid, membatasi HTTP methods GET/POST/PUT/DELETE, dan membangun endpoint CRUD dasar yang mengembalikan JSON.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Di episode 3 kita membuat aplikasi minimal dengan satu route. Sekarang kita memasuki inti dari semua web framework: routing. Setiap URL yang bisa diakses dari aplikasi kalian — /, /users, /posts/42 — adalah hasil dari sistem routing. Kuasai episode ini, dan kalian sudah memahami 80% cara kerja Flask. Kita akan membahas variabel path, converters, HTTP methods, hingga membangun endpoint CRUD dasar — yang menjadi fondasi REST API di episode 14.

Anatomi @app.route

PythonDua route pertama
from flask import Flask
 
app = Flask(__name__)
 
 
@app.route("/")
def index() -> str:
    return "Halaman utama"
 
 
@app.route("/about")
def about() -> str:
    return "Tentang kami"

/ menangani root, /about menangani halaman tentang. Flask mencocokkan path URL request ke pattern terdaftar — inilah URL dispatcher-nya. Perhatikan: tanpa method dinyatakan, route menangani semua method, yang jarang kita inginkan.

Menangkap Variabel Path

URL dinamis (/users/42, /posts/my-slug) memakai variabel path dengan syntax <nama>:

PythonPath parameter dasar
@app.route("/users/<username>")
def profile(username: str) -> str:
    return f"Profil {username}"
 
 
@app.route("/posts/<post_id>")
def post_detail(post_id: str) -> str:
    return f"Posting #{post_id}"

Variabel di dalam <...> secara otomatis diteruskan sebagai argumen ke fungsi. Tanpa converter, nilainya selalu bertipe str — termasuk angka. Karena itu, untuk data yang memang numerik, gunakan converter.

Converters: int, path, uuid

Converter membatasi dan mengonversi tipe variabel path:

ConverterCocok untukContoh
intBilangan bulat<int:user_id>
pathPath bertingkat (bisa berisi /)<path:file_path>
uuidUUID<uuid:token>
string (default)Tanpa /<username>
PythonConverter int, path, dan uuid
@app.route("/users/<int:user_id>")
def user_detail(user_id: int) -> str:
    return f"User ID {user_id} (tipe {type(user_id).__name__})"
 
 
@app.route("/files/<path:file_path>")
def serve_nested(file_path: str) -> str:
    return f"Path lengkap: {file_path}"
 
 
@app.route("/verify/<uuid:token>")
def verify(token: str) -> str:
    return f"Verifikasi token {token}"

<int:user_id> melakukan dua hal: menolak URL yang bukan angka (return 404 otomatis) dan mengubah nilainya menjadi int sebelum diteruskan. <path:...> menerima slash (/a/b/c), <uuid:...> hanya menerima UUID valid — konversi gagal otomatis jadi 404.

Tip

Gunakan converter sespesifik mungkin. <int:user_id> langsung membuang request GET /users/abc dengan 404 tanpa perlu validasi manual — lebih aman dan kode kalian lebih pendek. Ini salah satu pola yang langsung terasa manfaatnya di production.

HTTP Methods: GET, POST, PUT, DELETE

Secara default route menangani semua method. Batasi dengan argumen methods:

PythonSatu URL, banyak method
from flask import request
 
 
@app.route("/items/<int:item_id>", methods=["GET", "PUT", "DELETE"])
def item_ops(item_id: int) -> str:
    if request.method == "GET":
        return f"Membaca item {item_id}"
    if request.method == "PUT":
        return f"Memperbarui item {item_id}"
    return f"Menghapus item {item_id}"

Pola ini sering dipakai, tetapi Flask juga mendukung decorator per-method (@app.get, @app.post, @app.put, @app.delete, @app.patch) sejak 2.0 — lebih eksplisit:

PythonDecorator per method
@app.get("/items/<int:item_id>")
def read_item(item_id: int) -> str:
    return f"GET item {item_id}"
 
 
@app.put("/items/<int:item_id>")
def update_item(item_id: int) -> str:
    return f"PUT item {item_id}"
 
 
@app.delete("/items/<int:item_id>")
def delete_item(item_id: int) -> str:
    return f"DELETE item {item_id}"

Menggunakan @app.get dan sejenisnya membuat intent jelas, dan method yang tidak didukung otomatis mendapat 405 Method Not Allowed tanpa perlu if manual.

Endpoint CRUD Dasar dengan JSON

Sekarang kita rakit semuanya menjadi CRUD dasar memakai data di memori (belum database — itu episode 10):

Pythonapp.py - CRUD dasar dengan JSON
from flask import Flask, jsonify, request
 
app = Flask(__name__)
 
ITEMS: dict[int, str] = {1: "Keyboard", 2: "Mouse"}
 
 
@app.get("/items")
def list_items() -> dict:
    return jsonify({"items": ITEMS})
 
 
@app.get("/items/<int:item_id>")
def get_item(item_id: int) -> tuple[dict, int]:
    item = ITEMS.get(item_id)
    if item is None:
        return jsonify({"error": "item tidak ditemukan"}), 404
    return jsonify({"item_id": item_id, "name": item})
 
 
@app.post("/items")
def create_item() -> tuple[dict, int]:
    data = request.get_json()
    if not data or "name" not in data:
        return jsonify({"error": "field name wajib"}), 400
    new_id = max(ITEMS) + 1
    ITEMS[new_id] = data["name"]
    return jsonify({"item_id": new_id, "name": data["name"]}), 201
 
 
@app.delete("/items/<int:item_id>")
def remove_item(item_id: int) -> tuple[dict, int]:
    if item_id not in ITEMS:
        return jsonify({"error": "item tidak ditemukan"}), 404
    del ITEMS[item_id]
    return jsonify({"ok": True})

Perhatikan pola tuple[dict, int]: mengembalikan body JSON sekaligus status code (201 untuk created, 400 untuk bad request, 404 untuk not found). Uji dengan curl — misal curl -X POST http://127.0.0.1:5000/items -H "Content-Type: application/json" -d '{"name": "Monitor"}'.

request.get_json() membaca body JSON dari request; jika field wajib tidak ada, kita mengembalikan 400 dengan pesan error — pola validasi paling sederhana yang akan kita sempurnakan di episode 5 dan 12.

Common Pitfalls Routing

Beberapa kesalahan yang sering terjadi:

  • Slash di akhir URL: /items/ dan /items dianggap berbeda. Flask default redirect /items/ ke /items (dan sebaliknya) untuk menambah trailing slash, tetapi konsistensi di kalian lebih baik.
  • Method tidak dibatasi: route tanpa methods menerima semua method — kadang GET bisa menghapus data jika view-nya tidak berhati-hati.
  • ID numeric tanpa int converter: string "42" lolos validasi yang seharusnya numerik.

Penutup

Pada episode 4 ini, kalian telah menguasai fondasi routing Flask.

Inti yang harus dibawa pulang:

  • @app.route("/path/<var>") memetakan URL ke view function; variabel diteruskan sebagai argumen.
  • Converter (int, path, uuid) membatasi dan mengonversi nilai — pakai sespesifik mungkin.
  • Batasi method dengan @app.get, @app.post, dst — 405 otomatis untuk method tak didukung.
  • CRUD JSON dasar memakai jsonify() dan pola return jsonify(...), status.

Di episode 5 selanjutnya, kita membahas request, response, dan error handling secara utuh — objek request (args, form, json, files), konstruksi Response, redirect, status codes, @app.errorhandler, custom 404/500, dan format error API yang konsisten. Pastikan lab kalian siap, karena episode 5 penuh praktik!

Belajar Flask - Routing, URL & HTTP Methods | Belajar Flask