โปรเจกต์ Fullstack แรกของคุณ
รวม Python + Database + หน้าเว็บเป็นแอปสมบูรณ์ พร้อมแนวทางต่อยอด
🎉 ยินดีด้วย! คุณเกือบจะเป็น Fullstack Developer แล้ว
ตอนนี้คุณมีทักษะครบทุกชั้น:
- ✅ Python พื้นฐาน
- ✅ Backend API ด้วย FastAPI
- ✅ Database ด้วย SQL/SQLite
- ✅ Frontend พื้นฐาน (HTML/CSS/JS)
บทสุดท้ายนี้ เราจะ ประกอบร่าง เป็นแอปเดียว
แอปตัวอย่าง: "ร้านค้ามินิมอล"
แอปที่:
- แสดงรายการสินค้า (จาก database)
- เพิ่มสินค้าใหม่
- ลบสินค้า
โครงสร้างโปรเจกต์
my-shop/
├── venv/ ← virtual env (อย่าอัป Git)
├── main.py ← Backend (FastAPI)
├── shop.db ← database (สร้างอัตโนมัติ)
└── static/
├── index.html ← หน้าเว็บ
├── style.css
└── app.js
1. Backend (main.py)
import sqlite3
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
class Product(BaseModel):
name: str
price: float
def get_db():
conn = sqlite3.connect("shop.db")
conn.row_factory = sqlite3.Row
return conn
@app.on_event("startup")
def startup():
conn = get_db()
conn.execute("""
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price REAL
)
""")
conn.commit()
conn.close()
@app.get("/api/products")
def list_products():
conn = get_db()
rows = conn.execute("SELECT * FROM products").fetchall()
conn.close()
return [dict(r) for r in rows]
@app.post("/api/products")
def create_product(product: Product):
conn = get_db()
cursor = conn.execute(
"INSERT INTO products (name, price) VALUES (?, ?)",
(product.name, product.price)
)
conn.commit()
new_id = cursor.lastrowid
conn.close()
return {"id": new_id, "name": product.name, "price": product.price}
@app.delete("/api/products/{product_id}")
def delete_product(product_id: int):
conn = get_db()
conn.execute("DELETE FROM products WHERE id = ?", (product_id,))
conn.commit()
conn.close()
return {"message": "ลบแล้ว"}
# เสิร์ฟหน้าเว็บจากโฟลเดอร์ static
app.mount("/", StaticFiles(directory="static", html=True), name="static")
2. Frontend
static/index.html:
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8" />
<title>ร้านค้ามินิมอล</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>🛒 ร้านค้ามินิมอล</h1>
<form id="add-form">
<input name="name" placeholder="ชื่อสินค้า" required />
<input name="price" type="number" placeholder="ราคา" required />
<button>เพิ่ม</button>
</form>
<ul id="list"></ul>
<script src="app.js"></script>
</body>
</html>
static/style.css:
body {
font-family: sans-serif;
max-width: 500px;
margin: 40px auto;
background: #f5f5f5;
}
h1 { color: #2563eb; }
input, button {
padding: 8px;
margin: 4px 2px;
border-radius: 6px;
border: 1px solid #ccc;
}
button {
background: #2563eb;
color: white;
cursor: pointer;
}
li {
background: white;
padding: 12px;
border-radius: 8px;
margin: 8px 0;
list-style: none;
display: flex;
justify-content: space-between;
}
static/app.js:
const API = "/api/products";
async function loadProducts() {
const res = await fetch(API);
const products = await res.json();
const list = document.getElementById("list");
list.innerHTML = "";
for (const p of products) {
const li = document.createElement("li");
li.innerHTML = `<span>${p.name} — ${p.price} บาท</span>`;
const btn = document.createElement("button");
btn.textContent = "ลบ";
btn.onclick = async () => {
await fetch(`${API}/${p.id}`, { method: "DELETE" });
loadProducts();
};
li.appendChild(btn);
list.appendChild(li);
}
}
document.getElementById("add-form").addEventListener("submit", async (e) => {
e.preventDefault();
const form = e.target;
await fetch(API, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: form.name.value,
price: Number(form.price.value),
}),
});
form.reset();
loadProducts();
});
loadProducts();
3. รัน
# ติดตั้ง (ครั้งแรก)
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install fastapi "uvicorn[standard]"
# รัน
uvicorn main:app --reload
เปิด http://localhost:8000 — ลองเพิ่ม/ลบสินค้า แล้วรีเฟรชดู ข้อมูล อยู่ครบ! 🎉
💡 สังเกตว่าเรา mount static ที่
/ทำให้หน้าเว็บและ API อยู่ ที่เดียวกัน จึงเรียก API ด้วยแค่/api/products(ไม่ต้องใส่โดเมน)
ทำไมต้องเขียนโปรเจกต์จริง?
- ฝึก เชื่อม ความรู้ทุกชิ้นเข้าด้วยกัน
- เจอปัญหาจริง → เรียนรู้ลึก
- สร้าง พอร์ตโฟลิโอ ให้ผู้จ้างเห็น
💡 อย่า copy ทั้งดุ้น พิมพ์เอง แก้เอง พังเอง แก้เอง — นั่นคือวิธีเรียนรู้จริง
ไอเดียโปรเจกต์ต่อยอด
- To-do List — เพิ่ม/ทำเครื่องหมายเสร็จ/ลด งาน
- บันทึกการเงิน — รายรับ-รายจ่าย สรุปยอด
- API สภาพอากาศ — ดึงข้อมูลจาก API สาธารณะ
- บล็อก — โพสต์บทความ + ความคิดเห็น
- line bot — ทำบอทตอบข้อความ
บันไดการเติบโตต่อไป
| ขั้น | เรียนเพิ่ม |
|---|---|
| Python ลึกขึ้น | OOP, decorator, async/await |
| Backend ลึก | Authentication (JWT), testing (pytest) |
| Database ลึก | PostgreSQL, SQLAlchemy (ORM) |
| Frontend ทันสมัย | React (เรียนเพิ่มจากสาย JS) |
| Data / AI | pandas, numpy, scikit-learn |
| DevOps | Docker, Deploy (Railway/Render/Fly.io) |
Deploy ขึ้นเน็ตจริง
- Backend (FastAPI): Railway, Render, Fly.io
- Database: Supabase (PostgreSQL ฟรี)
- Frontend: ฝังใน Backend ก็ได้ หรือแยกไป Vercel
ข้อความสุดท้าย
คุณเริ่มจาก 0 ตอนนี้คุณสร้างแอป Fullstack ได้แล้ว — นี่เป็นความสำเร็จใหญ่!
จำไว้:
- 🌱 เรียนรู้ไม่มีที่สิ้นสุด — ทุกคนยังเรียนทุกวัน
- 🔁 ลงมือทำ สำคัญกว่าอ่านอย่างเดียว
- 🧠 เจอ error = โอกาสเรียนรู้ ไม่ใช่ความล้มเหลว
- 💪 อดทน — สายนี้ต้องใช้เวลา แต่คุ้มทุกวินาที
ขอให้สนุกกับการเดินทางในโลกของนักพัฒนา คุณทำได้! 🚀🎉
อ่านจบแล้ว? ทำเครื่องหมายว่าเสร็จเพื่อบันทึกความคืบหน้า
แบบทดสอบ
ตอบให้ครบแล้วกด “ตรวจคำตอบ” เพื่อเช็คความเข้าใจ
1. สถาปัตยกรรม Fullstack ของสาย Python ประกอบด้วยชั้นใด?
2. วิธีที่หน้าเว็บสื่อสารกับ FastAPI คือ?
3. หลังเรียนจบ สิ่งที่ควรทำต่อคือ?
กำลังโหลด…