⏱️ ~12 นาที

โปรเจกต์ Fullstack แรกของคุณ

รวมทุกสิ่งที่เรียนมาเป็นแอปสมบูรณ์ พร้อมแนวทางต่อยอด

🎉 ยินดีด้วย! คุณเกือบจะเป็น Fullstack Developer แล้ว

ตอนนี้คุณมีทักษะครบทุกชั้น:

  • ✅ JavaScript พื้นฐาน
  • ✅ HTML/CSS + DOM
  • ✅ Backend ด้วย Express
  • ✅ Database ด้วย SQL
  • ✅ Frontend ทันสมัยด้วย React

บทสุดท้ายนี้ เราจะ ประกอบร่าง ทุกอย่างเป็นแอปเดียว

แอปตัวอย่าง: "ร้านค้ามินิมอล"

เราจะสร้างแอปที่:

  • แสดงรายการสินค้า (จาก database)
  • เพิ่มสินค้าใหม่ได้
  • ลบสินค้าได้

โครงสร้างโปรเจกต์

my-shop/
├── server/              ← Backend
│   ├── index.js
│   ├── shop.db          (สร้างอัตโนมัติ)
│   └── package.json
└── client/              ← Frontend (React)
    ├── src/
    │   ├── App.jsx
    │   └── main.jsx
    └── package.json

Backend (server/index.js)

const express = require("express");
const sqlite3 = require("sqlite3").verbose();
const cors = require("cors");

const app = express();
app.use(cors());
app.use(express.json());

const db = new sqlite3.Database("./shop.db");

db.serialize(() => {
  db.run(`
    CREATE TABLE IF NOT EXISTS products (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      price REAL
    )
  `);
});

// ดูทั้งหมด
app.get("/products", (req, res) => {
  db.all("SELECT * FROM products", [], (err, rows) => {
    if (err) return res.status(500).json({ error: err.message });
    res.json(rows);
  });
});

// เพิ่มใหม่
app.post("/products", (req, res) => {
  const { name, price } = req.body;
  db.run(
    "INSERT INTO products (name, price) VALUES (?, ?)",
    [name, price],
    function (err) {
      if (err) return res.status(500).json({ error: err.message });
      res.status(201).json({ id: this.lastID, name, price });
    }
  );
});

// ลบ
app.delete("/products/:id", (req, res) => {
  db.run("DELETE FROM products WHERE id = ?", [req.params.id], () => {
    res.status(204).send();
  });
});

app.listen(3000, () => console.log("Backend: http://localhost:3000"));

Frontend (client/src/App.jsx)

import { useState, useEffect } from "react";

const API = "http://localhost:3000";

function App() {
  const [products, setProducts] = useState([]);
  const [name, setName] = useState("");
  const [price, setPrice] = useState("");

  // ดึงสินค้าตอนเปิดแอป
  async function loadProducts() {
    const res = await fetch(`${API}/products`);
    const data = await res.json();
    setProducts(data);
  }

  useEffect(() => {
    loadProducts();
  }, []);

  // เพิ่มสินค้า
  async function addProduct(e) {
    e.preventDefault();
    await fetch(`${API}/products`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name, price: Number(price) }),
    });
    setName("");
    setPrice("");
    loadProducts();
  }

  // ลบสินค้า
  async function deleteProduct(id) {
    await fetch(`${API}/products/${id}`, { method: "DELETE" });
    loadProducts();
  }

  return (
    <div style={{ maxWidth: 500, margin: "40px auto", fontFamily: "sans-serif" }}>
      <h1>🛒 ร้านค้ามินิมอล</h1>

      <form onSubmit={addProduct} style={{ marginBottom: 20 }}>
        <input
          value={name}
          onChange={e => setName(e.target.value)}
          placeholder="ชื่อสินค้า"
          required
        />
        <input
          value={price}
          onChange={e => setPrice(e.target.value)}
          type="number"
          placeholder="ราคา"
          required
        />
        <button type="submit">เพิ่ม</button>
      </form>

      <ul>
        {products.map(p => (
          <li key={p.id}>
            {p.name} — {p.price} บาท{" "}
            <button onClick={() => deleteProduct(p.id)}>ลบ</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

รันทั้งสองฝั่ง

เปิด terminal ที่ 1 (Backend):

cd server
npm install express sqlite3 cors
node index.js

เปิด terminal ที่ 2 (Frontend):

npm create vite@latest client -- --template react
cd client
npm install
npm run dev

เปิด http://localhost:5173 — ลองเพิ่ม/ลบสินค้า แล้วรีเฟรชดู ข้อมูล อยู่ครบ! 🎉

💡 นี่คือ แอป Fullstack ของคุณเอง — Frontend พูดกับ Backend ผ่าน API และ Backend เก็บข้อมูลใน Database ถาวร

ทำไมต้องเขียนโปรเจกต์จริง?

  • ฝึก เชื่อม ความรู้ทุกชิ้นเข้าด้วยกัน
  • เจอปัญหาจริง → เรียนรู้ลึก
  • สร้าง พอร์ตโฟลิโอ ให้ผู้จ้างเห็น

💡 คำแนะนำ: อย่า copy โค้ดนี้ทั้งดุ้น พิมพ์เอง แก้เอง พังเอง แก้เอง นั่นคือวิธีที่เรียนรู้จริง

ไอเดียโปรเจกต์ต่อยอด

เริ่มจากง่าย → ยาก:

  1. To-do List — เพิ่ม/ทำเครื่องหมายเสร็จ/ลด งาน
  2. บันทึกการเงิน — บันทึกรายรับ-รายจ่าย สรุปยอด
  3. บล็อกส่วนตัว — โพสต์บทความ (มีรูป, ความคิดเห็น)
  4. ระบบจอง — จองคิว/ห้อง (มีวันเวลา)
  5. แชทเรียลไทม์ — ใช้ WebSocket (โค้ดยากขึ้น)

บันไดการเติบโตต่อไป

ขั้นเรียนเพิ่ม
พื้นฐานมั่นคงTypeScript (JS ที่มี type), Git ลึกขึ้น
Frontend ลึกReact Router, state management (Zustand/Redux)
Backend ลึกAuthentication (JWT), ทดสอบ (testing)
Database ลึกPostgreSQL, relations, index
DevOpsDocker, CI/CD, Deploy (Vercel/Railway)

Deploy ขึ้นเน็ตจริง

พอแอปใช้ได้แล้ว อยากให้คนอื่นเห็น:

  • Frontend: Vercel, Netlify, Cloudflare Pages
  • Backend: Railway, Render, Fly.io
  • Database: Supabase, Neon (PostgreSQL ฟรี)

ลองหา tutorial "deploy MERN" หรือ "deploy React + Express" ตามดูได้เลย

ข้อความสุดท้าย

คุณเริ่มจาก 0 ตอนนี้คุณสร้างแอป Fullstack ได้แล้ว — นี่เป็นความสำเร็จใหญ่!

จำไว้:

  • 🌱 เรียนรู้ไม่มีที่สิ้นสุด — ทุกโปรแกรมเมอร์ยังเรียนทุกวัน
  • 🔁 ลงมือทำ สำคัญกว่าอ่านอย่างเดียว
  • 🧠 เจอ error = โอกาสเรียนรู้ ไม่ใช่ความล้มเหลว
  • 💪 อดทน — สายนี้ต้องใช้เวลา แต่คุ้มทุกวินาที

ขอให้สนุกกับการเดินทางในโลกของนักพัฒนา คุณทำได้! 🚀🎉

อ่านจบแล้ว? ทำเครื่องหมายว่าเสร็จเพื่อบันทึกความคืบหน้า

🧠

แบบทดสอบ

ตอบให้ครบแล้วกด “ตรวจคำตอบ” เพื่อเช็คความเข้าใจ

  1. 1. สถาปัตยกรรม Fullstack ที่เราสร้างประกอบด้วยชั้นใดบ้าง?

  2. 2. วิธีที่ Frontend สื่อสารกับ Backend คือ?

  3. 3. หลังเรียนจบหลักสูตร สิ่งที่ควรทำต่อคือ?

กำลังโหลด…