Web Server #
Python memiliki ekosistem web server yang kaya — dari modul bawaan untuk kebutuhan sederhana, hingga framework lengkap untuk aplikasi skala produksi. Memilih yang tepat bergantung pada kompleksitas proyek, kebutuhan performa, dan seberapa banyak “baterai” yang kamu inginkan sudah terpasang. Artikel ini membahas empat pilihan utama dengan contoh yang cukup nyata untuk menunjukkan karakter masing-masing: http.server, Flask, FastAPI, dan Django.
WSGI vs ASGI #
Sebelum memilih framework, penting memahami dua model interface web Python karena ini mempengaruhi performa dan ekosistem deployment.
WSGI (Web Server Gateway Interface) ASGI (Asynchronous SGI)
──────────────────────────────────── ──────────────────────────
Model: synchronous Model: asynchronous (async/await)
Server: Gunicorn, uWSGI Server: Uvicorn, Hypercorn, Daphne
Framework: Flask, Django Framework: FastAPI, Django (3.0+), Starlette
Cocok: request-response biasa Cocok: WebSocket, long-polling, streaming
Concurrency: multi-process/thread Concurrency: event loop (lebih efisien I/O)
http.server — Server Development Cepat
#
Modul bawaan Python, tidak perlu instalasi apapun. Berguna untuk menyajikan file statis sementara saat development — bukan untuk production.
import http.server
import socketserver
PORT = 8000
# SimpleHTTPRequestHandler: sajikan file dari direktori saat ini
with socketserver.TCPServer(("", PORT), http.server.SimpleHTTPRequestHandler) as httpd:
print(f"Serving di http://localhost:{PORT}")
httpd.serve_forever()
Atau langsung dari terminal tanpa menulis kode:
# Python 3 — sajikan direktori saat ini di port 8000
python -m http.server 8000
# Tentukan direktori spesifik
python -m http.server 8000 --directory /path/ke/folder
http.server tidak cocok untuk production — tidak ada autentikasi, tidak ada keamanan, dan performanya sangat terbatas. Gunakan hanya untuk development lokal atau berbagi file sementara di jaringan internal.Flask — Microframework Fleksibel #
Flask memberikan kamu fondasi minimal: routing dan request/response handling. Sisanya kamu pilih sendiri — database, autentikasi, validasi. Cocok untuk REST API sederhana hingga menengah, atau saat kamu ingin kontrol penuh atas arsitektur.
pip install flask
Routing dan Response #
from flask import Flask, request, jsonify, abort
app = Flask(__name__)
# Data simulasi (normalnya dari database)
produk_db = {
1: {"id": 1, "nama": "Laptop", "harga": 12000000},
2: {"id": 2, "nama": "Mouse", "harga": 250000},
}
@app.route("/produk", methods=["GET"])
def daftar_produk():
"""GET /produk — kembalikan semua produk."""
return jsonify(list(produk_db.values()))
@app.route("/produk/<int:produk_id>", methods=["GET"])
def detail_produk(produk_id):
"""GET /produk/:id — kembalikan satu produk berdasarkan ID."""
produk = produk_db.get(produk_id)
if produk is None:
abort(404) # Flask akan kembalikan respons 404 otomatis
return jsonify(produk)
@app.route("/produk", methods=["POST"])
def tambah_produk():
"""POST /produk — tambah produk baru dari JSON body."""
data = request.get_json()
if not data or "nama" not in data or "harga" not in data:
return jsonify({"error": "Field 'nama' dan 'harga' wajib diisi."}), 400
id_baru = max(produk_db.keys()) + 1
produk_baru = {"id": id_baru, "nama": data["nama"], "harga": data["harga"]}
produk_db[id_baru] = produk_baru
return jsonify(produk_baru), 201 # 201 Created
@app.route("/produk/<int:produk_id>", methods=["DELETE"])
def hapus_produk(produk_id):
"""DELETE /produk/:id — hapus produk."""
if produk_id not in produk_db:
abort(404)
del produk_db[produk_id]
return "", 204 # 204 No Content
if __name__ == "__main__":
# debug=True hanya untuk development — matikan di production!
app.run(host="0.0.0.0", port=5000, debug=True)
Penanganan Error Terpusat #
@app.errorhandler(404)
def tidak_ditemukan(error):
return jsonify({"error": "Resource tidak ditemukan."}), 404
@app.errorhandler(500)
def server_error(error):
return jsonify({"error": "Terjadi kesalahan internal server."}), 500
Jangan gunakanapp.run()di production. Server development Flask single-threaded dan tidak aman. Untuk production, jalankan Flask dengan WSGI server seperti Gunicorn:gunicorn -w 4 -b 0.0.0.0:5000 app:app(4 worker process).
FastAPI — API Modern dengan Type Hints #
FastAPI memanfaatkan type hints Python untuk validasi input otomatis, serialisasi response, dan dokumentasi interaktif yang di-generate secara otomatis. Performanya setara dengan Node.js dan Go untuk I/O-bound tasks berkat ASGI.
pip install fastapi uvicorn
Routing, Validasi, dan Dokumentasi Otomatis #
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel, Field
from typing import Optional
app = FastAPI(title="API Produk", version="1.0.0")
# Pydantic model: definisi sekaligus validasi dan dokumentasi
class ProdukCreate(BaseModel):
nama: str = Field(..., min_length=1, max_length=100, description="Nama produk")
harga: int = Field(..., gt=0, description="Harga dalam rupiah, harus positif")
stok: Optional[int] = Field(default=0, ge=0)
class Produk(ProdukCreate):
id: int
# Data simulasi
produk_db: dict[int, Produk] = {
1: Produk(id=1, nama="Laptop", harga=12000000, stok=5),
2: Produk(id=2, nama="Mouse", harga=250000, stok=20),
}
@app.get("/produk", response_model=list[Produk])
def daftar_produk(skip: int = 0, limit: int = 10):
"""
Ambil daftar produk dengan pagination.
- **skip**: jumlah item yang dilewati
- **limit**: jumlah item maksimal yang dikembalikan
"""
items = list(produk_db.values())
return items[skip : skip + limit]
@app.get("/produk/{produk_id}", response_model=Produk)
def detail_produk(produk_id: int):
"""Ambil detail satu produk berdasarkan ID."""
if produk_id not in produk_db:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Produk dengan ID {produk_id} tidak ditemukan."
)
return produk_db[produk_id]
@app.post("/produk", response_model=Produk, status_code=status.HTTP_201_CREATED)
def tambah_produk(produk: ProdukCreate):
"""
Tambah produk baru.
FastAPI otomatis memvalidasi body request berdasarkan ProdukCreate.
Jika validasi gagal, 422 Unprocessable Entity dikembalikan otomatis.
"""
id_baru = max(produk_db.keys()) + 1
produk_baru = Produk(id=id_baru, **produk.model_dump())
produk_db[id_baru] = produk_baru
return produk_baru
@app.delete("/produk/{produk_id}", status_code=status.HTTP_204_NO_CONTENT)
def hapus_produk(produk_id: int):
"""Hapus produk berdasarkan ID."""
if produk_id not in produk_db:
raise HTTPException(status_code=404, detail="Produk tidak ditemukan.")
del produk_db[produk_id]
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
Setelah server jalan, FastAPI menyediakan dokumentasi interaktif secara otomatis:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
FastAPI menggunakan Pydantic untuk validasi — jika request body tidak sesuai schema, FastAPI otomatis mengembalikan 422 Unprocessable Entity dengan detail field mana yang salah, tanpa kamu perlu menulis kode validasi manual.Django — Framework Full-Featured #
Django hadir dengan “batteries included”: ORM, admin panel, autentikasi, form handling, migrations — semuanya sudah tersedia. Cocok untuk aplikasi web kompleks yang butuh banyak fitur siap pakai.
pip install django djangorestframework
Membuat Proyek dan Aplikasi #
django-admin startproject toko . # buat proyek (titik = di direktori saat ini)
python manage.py startapp produk # buat aplikasi
python manage.py migrate # jalankan migrasi awal
python manage.py runserver # jalankan development server
Struktur proyek yang dihasilkan:
toko/
├── manage.py
├── toko/
│ ├── settings.py ← konfigurasi proyek
│ ├── urls.py ← routing utama
│ └── wsgi.py
└── produk/
├── models.py ← definisi model/tabel database
├── views.py ← logika request/response
├── urls.py ← routing aplikasi
└── admin.py ← konfigurasi admin panel
Contoh Model dan View Sederhana #
# produk/models.py
from django.db import models
class Produk(models.Model):
nama = models.CharField(max_length=100)
harga = models.PositiveIntegerField()
stok = models.PositiveIntegerField(default=0)
dibuat_pada = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.nama
class Meta:
ordering = ["-dibuat_pada"]
# produk/views.py — menggunakan Django REST Framework
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import serializers
from .models import Produk
class ProdukSerializer(serializers.ModelSerializer):
class Meta:
model = Produk
fields = "__all__"
class ProdukViewSet(viewsets.ModelViewSet):
"""
ViewSet otomatis menyediakan:
GET /produk/ → list semua produk
POST /produk/ → tambah produk baru
GET /produk/{id}/ → detail satu produk
PUT /produk/{id}/ → update produk
DELETE /produk/{id}/ → hapus produk
"""
queryset = Produk.objects.all()
serializer_class = ProdukSerializer
# Buat dan jalankan migrasi setelah mendefinisikan model
python manage.py makemigrations produk
python manage.py migrate
Perbandingan dan Panduan Memilih #
http.server Flask FastAPI Django
────────── ────────── ────────── ──────────
Tujuan File statis REST API REST API Full-stack
Interface WSGI WSGI ASGI WSGI/ASGI
Kurva belajar Sangat mudah Mudah Mudah-sedang Sedang-tinggi
Validasi input ✗ Manual Otomatis Otomatis (DRF)
Dokumentasi API ✗ Manual Otomatis Manual/DRF
ORM bawaan ✗ ✗ ✗ ✓
Admin panel ✗ ✗ ✗ ✓
Production ✗ Gunicorn Uvicorn Gunicorn/Uvicorn
Pilih Flask jika:
✓ Butuh REST API sederhana dengan kontrol penuh
✓ Tim sudah familiar dengan Flask
✓ Tidak butuh validasi otomatis atau dokumentasi
✓ Butuh fleksibilitas memilih komponen sendiri
Pilih FastAPI jika:
✓ Butuh REST API dengan validasi ketat dan dokumentasi otomatis
✓ Performa tinggi untuk I/O-bound tasks
✓ Tim nyaman dengan type hints dan async/await
✓ Ingin API docs (Swagger) tanpa effort tambahan
Pilih Django jika:
✓ Butuh aplikasi web lengkap: auth, admin, ORM, form
✓ Ingin "batteries included" tanpa merakit sendiri
✓ Proyek skala besar dengan tim yang besar
✓ Butuh admin panel yang bisa dikustomisasi
Ringkasan #
http.serverhanya untuk development lokal — tidak aman dan tidak performan untuk production.- Flask adalah microframework WSGI yang fleksibel — kamu pilih sendiri semua komponennya; cocok untuk REST API sederhana hingga menengah.
- FastAPI adalah framework ASGI modern — validasi input otomatis via Pydantic, dokumentasi Swagger auto-generated, dan performa tinggi; cocok untuk API yang perlu type safety dan developer experience terbaik.
- Django hadir dengan semua fitur siap pakai — ORM, admin, autentikasi, migrations; cocok untuk aplikasi web kompleks yang butuh produktivitas tinggi dari awal.
- Jangan gunakan
app.run()Flask di production — gunakan Gunicorn untuk WSGI, Uvicorn untuk ASGI.- WSGI (Flask, Django) untuk request-response sinkron; ASGI (FastAPI, Django 3+) untuk WebSocket, streaming, dan async handler.
- Pilih framework berdasarkan kebutuhan proyek, bukan popularitas — masing-masing punya trade-off yang berbeda.