จะเริ่ม backend ด้วย Django, FastAPI หรือ Flask ให้ลองงานเล็กที่เหมือนกันก่อน: รับชื่อผ่าน URL ตรวจข้อมูล แล้วตอบ JSON บทความนี้พาทำทีละตัว พร้อมแยกสิ่งที่ framework เตรียมให้กับสิ่งที่ทีมยังต้องออกแบบเอง

เลือกจากงานที่ต้องดูแล

ตัวเลือกจุดเริ่มที่เหมาะสิ่งที่ยังต้องคิด
Djangoระบบข้อมูลที่ต้องมี model, migration, admin และผู้ใช้โครงสร้างแอปและ middleware มีมากกว่าตัวอย่าง API นี้; ORM ไม่ได้ออกแบบ schema ให้เอง
FastAPIAPI ที่ต้องการ validation จาก type hint และเอกสาร OpenAPIยังต้องเลือกฐานข้อมูล migration งานเบื้องหลัง และวิธีจัดสิทธิ์
Flaskบริการเล็กหรือทีมที่อยากเลือกส่วนประกอบเองvalidation, ORM, auth และเอกสาร API ต้องเลือกและประกอบให้เหมาะ

เปิด ตาราง Django / FastAPI / Flask เพื่อดูบทบาทและข้อจำกัดคู่กับ คลัง Python จำนวน dependency น้อยไม่ได้แปลว่าดูแลระบบจริงง่ายกว่าเสมอ

ภาพปกเป็นสัดส่วนผู้ตอบคำถาม WebFramework ใน Stack Overflow Developer Survey 2026: Django 11.3% (1,160 คน), FastAPI 18.5% (1,903 คน), Flask 12.5% (1,284 คน) จากผู้ตอบคำถาม 10,281 คน เลือกได้หลายข้อและสมัครใจตอบ จึงใช้เป็นบริบทของชุมชน ไม่ใช่ส่วนแบ่งตลาดไทยหรือผลวัดความเร็ว ดู วิธีสำรวจ ข้อมูลโดย Stack Exchange Inc. ภายใต้ ODbL 1.0 กราฟวาดใหม่โดย Reefsight

เตรียม Python และแยก environment

ชุดที่ทดลองใช้ Python 3.12.14 บน macOS arm64 โดย Django 6.1.2, FastAPI 0.143.3, Uvicorn 0.54.0 และ Flask 3.1.3 เป็นเวอร์ชันที่ติดตั้งจริง ตรวจวันที่และ release ปัจจุบันก่อนเริ่มโปรเจกต์ใหม่ ชุดนี้ตรึงรุ่นเพื่อให้เทียบกับตัวอย่างได้

Terminal
python3 --version
mkdir django-demo
cd django-demo
python3 -m venv .venv
source .venv/bin/activate
python -m pip install Django==6.1.2

บน Windows ใช้ py -3.12 -m venv .venv แล้วเปิด environment ด้วย .venv\Scripts\Activate.ps1 ใน PowerShell หากนโยบายเครื่องไม่ให้ activate ให้เรียก .venv\Scripts\python.exe ตรง ๆ ไม่ต้องแก้นโยบายความปลอดภัยเพื่อทำตามบทความ เรารันทดสอบบน macOS; คำสั่ง Windows อธิบายไว้สำหรับการปรับใช้ ยังไม่ได้รันบน Windows

ในห้องทดลองใช้ uv venv --seed เพื่อเตรียม environment จาก Python 3.12.14 ที่มีอยู่ แล้วติดตั้ง package ด้วย python -m pip ชุดเดียวกัน แยกหนึ่ง environment ต่อ framework และบันทึก pip freeze ไว้ทุกชุด

Django: สร้าง project แล้วผูก URL กับ view

Terminal
python -m django startproject config .
python manage.py migrate

ใช้ Django tutorial เป็นโครงเริ่มต้น แทนที่ไฟล์สองไฟล์นี้ ตัวอย่างยังคง middleware มาตรฐานไว้ ไม่ปิด CSRF เพื่อให้ POST ที่ไม่พร้อมผ่าน

config/views.py

python
from django.http import JsonResponse
from django.views.decorators.http import require_GET
@require_GET
def hello(request):
    name = request.GET.get('name', 'โลก').strip()
    if not name or len(name) > 40:
        return JsonResponse({'error': 'ชื่อต้องมี 1–40 ตัวอักษร'}, status=400)
    return JsonResponse({'message': f'สวัสดี {name}'})

config/urls.py

python
from django.urls import path
from .views import hello
urlpatterns = [path('hello', hello)]
Terminal
python manage.py check
python manage.py runserver 127.0.0.1:8000

JsonResponse จัดรูปแบบ JSON และ header ให้ ส่วนเงื่อนไขชื่อว่าง/ยาวเป็นกติกาที่เราเขียนเอง อ้างอิง request และ response

FastAPI: ประกาศชนิดข้อมูลกับข้อจำกัดของ query

เปิด terminal ใหม่แล้วสร้าง fastapi-demo กับ environment แยกเหมือนขั้นก่อน จากนั้นติดตั้ง:

Terminal
python -m pip install fastapi==0.143.3 uvicorn==0.54.0

main.py

python
from typing import Annotated
from fastapi import FastAPI, HTTPException, Query
app = FastAPI()
@app.get('/hello')
def hello(name: Annotated[str, Query(min_length=1, max_length=40)] = 'โลก'):
    name = name.strip()
    if not name:
        raise HTTPException(status_code=422, detail='ชื่อต้องมี 1–40 ตัวอักษร')
    return {'message': f'สวัสดี {name}'}
Terminal
python -m uvicorn main:app --host 127.0.0.1 --port 8001

ลองเปิด http://127.0.0.1:8001/docs เพื่อดู OpenAPI UI ที่ framework สร้างจาก endpoint; ไม่ใช่เอกสารกติกาธุรกิจที่ครบโดยอัตโนมัติ Query ตรวจความยาวก่อนเข้า function ส่วนชื่อที่เป็นช่องว่างล้วนตรวจหลัง strip() ดู First Steps และ Query validation

Flask: เริ่มจาก route ขนาดเล็ก

สร้าง flask-demo และ environment อีกชุดตาม คู่มือติดตั้ง Flask:

Terminal
python -m pip install Flask==3.1.3

app.py

python
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.get('/hello')
def hello():
    name = request.args.get('name', 'โลก').strip()
    if not name or len(name) > 40:
        return jsonify(error='ชื่อต้องมี 1–40 ตัวอักษร'), 400
    return jsonify(message=f'สวัสดี {name}')
Terminal
python -m flask --app app run --host 127.0.0.1 --port 8002

request.args อ่าน query และ jsonify สร้าง JSON; validation กับรูปแบบ error ยังเป็นการตัดสินใจของผู้เขียน อ่าน Flask quickstart ประกอบ

ทดลองคำขอเดียวกันและอ่าน status จริง

แทน port ด้วย 8000, 8001 หรือ 8002 ตาม server ที่เปิดไว้:

Terminal
curl -i 'http://127.0.0.1:8000/hello?name=ReefSight'
curl -i 'http://127.0.0.1:8000/hello?name='
curl -i 'http://127.0.0.1:8000/hello'

คำขอแรกตอบ JSON {"message":"สวัสดี ReefSight"} พร้อม 200; ไม่ส่งชื่อจะใช้ “โลก” ชื่อว่างหรือยาวเกิน 40 ตัวอักษรตอบ 400 ใน Django/Flask และ 422 ใน FastAPI ตาม validation ที่ใช้ รูปแบบ error จึงต่างกัน หาก client ต้องคุยกับหลายบริการ ทีมควรกำหนด error contract ร่วมกัน ไม่ใช่สมมติว่าทุก framework ส่งเหมือนกัน

Reefsight รันตรวจ HTTP จริงครบ 19 กรณี: ค่าปริยาย ชื่อปกติ ภาษาไทย ชื่อว่าง ชื่อเกินความยาว และ POST ในทั้งสามชุด พร้อมตรวจ /openapi.json ของ FastAPI การส่ง POST ที่ไม่มี CSRF token ได้ 403 จาก Django middleware ก่อนถึง view; อีกสองชุดได้ 405 เพราะ route รับ GET ไม่ใช่เหตุผลให้ปิด CSRF

ไม่มีการวัด throughput/latency เปรียบเทียบ และยังไม่ได้ทดสอบฐานข้อมูลจริง ระบบสมาชิก concurrency สูง หรือ browser/OS อื่น ผลนี้ยืนยันเส้นทางเริ่มต้นและคำตอบของตัวอย่างเท่านั้น

ก่อนเปลี่ยนจากตัวอย่างเป็นบริการจริง

เก็บ version ที่ติดตั้งด้วย python -m pip freeze > requirements.lock.txt แล้วทดสอบการติดตั้งซ้ำใน environment ใหม่ แยก secret ออกจาก code, จำกัดสิทธิ์ฐานข้อมูล, ออกแบบ authentication/authorization, logging และการรับมือ error ก่อนเปิดสาธารณะ

Django และ Flask development server ไม่ใช่ server สำหรับ production ส่วน Uvicorn ต้องวางแผน HTTPS, process supervision และจำนวน worker ให้ตรงงาน ไม่ใช้ผลจากเครื่องเดียวตัดสินว่า framework ใดเร็วที่สุด อ่าน Django deployment checklist, FastAPI server deployment และ Flask production deployment แล้วทดลอง deploy แยกจากโปรเจกต์จริงก่อน

คุยกับทีม Reefsight