แสดงบทความที่มีป้ายกำกับ Web Development แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ Web Development แสดงบทความทั้งหมด

วันพฤหัสบดีที่ 3 เมษายน พ.ศ. 2568

การใช้ Toast Notifications ใน Next.js: แจ้งเตือนแบบโปร ไม่ต้องรีโหลดหน้า

เคยเจอปัญหานี้ไหม? กดปุ่มแล้วไม่รู้ว่าระบบทำงานหรือยัง ส่งฟอร์มแล้วไม่แน่ใจว่าผ่านหรือไม่ หรืออยากให้เว็บมีแจ้งเตือนที่ดูดีแต่ไม่อยากเขียนเองให้ยุ่งยาก

วันนี้เราจะมาเรียนรู้วิธีใช้ Toast Notifications ใน Next.js แบบง่ายๆ โดยใช้ react-hot-toast ไลบรารีสุดเทพที่ช่วยให้แจ้งเตือนแบบลื่นไหล ดูดี และใช้งานง่าย

🔥 ทำไมต้องใช้ Toast Notifications?

Toast Notifications คือ ข้อความแจ้งเตือนแบบชั่วคราว ที่แสดงขึ้นมาในเว็บเมื่อมีเหตุการณ์บางอย่างเกิดขึ้น เช่น:

✅ แจ้งเตือนเมื่อทำรายการสำเร็จ ✅
✅ แจ้งเตือนข้อผิดพลาด (เช่น ฟอร์มไม่ถูกต้อง) ❌
✅ แจ้งเตือนระหว่างโหลดข้อมูล ⏳

Toast ดีๆ ควรเป็น Non-intrusive (ไม่รบกวน) และ Auto-dismiss (หายไปเอง) เพื่อไม่ให้ผู้ใช้รำคาญ

🚀 ติดตั้ง react-hot-toast ใน Next.js

เราจะใช้ react-hot-toast เพราะมันใช้ง่ายและทำงานได้ดีกับ Next.js

ติดตั้งแพ็กเกจ

npm install react-hot-toast

หรือถ้าใช้ Yarn

yarn add react-hot-toast


🎨 ตั้งค่า ToastProvider

ToastProvider เป็นคอมโพเนนต์ที่ช่วยให้เราสามารถใช้ toast ได้ทั่วแอป ต้องเพิ่มใน _app.js

แก้ไข pages/_app.js

import { Toaster } from 'react-hot-toast';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Toaster position="top-right" reverseOrder={false} />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

🔹 position="top-right" – ให้ toast แสดงที่มุมขวาบน
🔹 reverseOrder={false} – ให้ข้อความใหม่ขึ้นด้านล่าง


🎯 ใช้งาน toast แจ้งเตือน

react-hot-toast ใช้งานง่ายมาก มีฟังก์ชันหลักๆ เช่น

  • toast.success("ข้อความ") ✅ แจ้งเตือนสำเร็จ
  • toast.error("ข้อความ") ❌ แจ้งเตือนข้อผิดพลาด
  • toast.loading("กำลังโหลด...") ⏳ แจ้งเตือนระหว่างโหลด
  • toast.dismiss() 🚫 ลบ toast ที่กำลังแสดง


💡 ตัวอย่างการใช้งาน toast ในปุ่ม

สร้างไฟล์ pages/index.js และเพิ่มปุ่มที่กดแล้วแจ้งเตือน

import toast from 'react-hot-toast';

export default function Home() {
  const notifySuccess = () => toast.success('บันทึกข้อมูลสำเร็จ! 🎉');
  const notifyError = () => toast.error('เกิดข้อผิดพลาด ❌');
  const notifyLoading = () => {
    const toastId = toast.loading('กำลังโหลดข้อมูล...');
    setTimeout(() => toast.success('โหลดสำเร็จ ✅', { id: toastId }), 2000);
  };

  return (
    <div className="p-10">
      <h1 className="text-2xl font-bold mb-4">🔔 ทดลองใช้ Toast Notifications</h1>
      <button onClick={notifySuccess} className="bg-green-500 text-white px-4 py-2 mr-2 rounded">✅ แจ้งเตือนสำเร็จ</button>
      <button onClick={notifyError} className="bg-red-500 text-white px-4 py-2 mr-2 rounded">❌ แจ้งเตือนข้อผิดพลาด</button>
      <button onClick={notifyLoading} className="bg-blue-500 text-white px-4 py-2 rounded">⏳ แจ้งเตือนระหว่างโหลด</button>
    </div>
  );
}

🔍 อธิบายโค้ด:

  • toast.success() ใช้แจ้งเตือนเมื่อทำรายการสำเร็จ
  • toast.error() ใช้แจ้งเตือนเมื่อเกิดข้อผิดพลาด
  • toast.loading() ใช้แจ้งเตือนว่ากำลังโหลดข้อมูล และอัปเดตเป็น toast.success() หลังจากโหลดเสร็จ


🎨 ปรับแต่งสไตล์ Toast

เราสามารถ กำหนดสไตล์ ของ toast ได้ เช่น เปลี่ยนสีพื้นหลัง เปลี่ยนไอคอน หรือกำหนดเวลาหายไปเอง

1️⃣ กำหนดเวลาให้ toast หายไปอัตโนมัติ

toast.success('บันทึกเรียบร้อย!', {
  duration: 5000, // แสดงผล 5 วินาที
});

2️⃣ เปลี่ยนสีและไอคอน

toast('🛑 คำเตือน: โปรดตรวจสอบข้อมูล', {
  style: {
    border: '1px solid red',
    padding: '16px',
    color: 'red',
  },
});

3️⃣ กำหนด animation

toast.success('ทำสำเร็จ!', {
  style: { animation: 'bounce 1s ease-in-out' },
});


🔄 ใช้ Toast กับ API Requests

ลองใช้ toast กับ API จริงๆ เช่น fetch()

const fetchData = async () => {
  const toastId = toast.loading('กำลังโหลดข้อมูล...');

  try {
    const response = await fetch('/api/data');
    const result = await response.json();

    toast.success('โหลดข้อมูลสำเร็จ!', { id: toastId });
  } catch (error) {
    toast.error('โหลดข้อมูลล้มเหลว', { id: toastId });
  }
};

🔍 อธิบาย:

  • toast.loading() แจ้งเตือนว่ากำลังโหลด
  • ถ้าโหลดสำเร็จ → toast.success()
  • ถ้าเกิดข้อผิดพลาด → toast.error()


📌 ใช้ Toast กับฟอร์ม

ในฟอร์มเราสามารถใช้ toast แจ้งเตือนว่า กรอกข้อมูลถูกต้องหรือไม่

const handleSubmit = (e) => {
  e.preventDefault();
 
  if (!email) {
    toast.error('กรุณากรอกอีเมล!');
    return;
  }

  toast.success('ส่งข้อมูลสำเร็จ!');
};

🏆 สรุป

✅ react-hot-toast ใช้งานง่ายมาก
✅ ใช้กับ API Requests, ฟอร์ม และปุ่มต่างๆ ได้
✅ ปรับแต่งสไตล์และอนิเมชันได้
✅ ไม่ต้องรีโหลดหน้า ก็แจ้งเตือนได้แบบสวยๆ

พร้อมใช้ Toast แจ้งเตือนให้เว็บของคุณดูโปรขึ้นหรือยัง? 🚀

วันพุธที่ 2 เมษายน พ.ศ. 2568

การสร้าง Dashboard UI ใน Next.js: ทำง่าย ใช้งานจริง แบบโปรๆ

เคยไหม? เวลาจะสร้าง Dashboard สวยๆ ในเว็บแอปพลิเคชันแต่ไม่รู้จะเริ่มตรงไหน? วันนี้เราจะมาลุยกันว่า Next.js จะช่วยให้เราสร้าง Dashboard UI ที่สวยงาม ใช้งานได้จริง และมีประสิทธิภาพได้ยังไง

🔥 ทำไมต้องใช้ Next.js สำหรับ Dashboard?

Next.js เป็นหนึ่งใน React Framework ที่เหมาะกับการสร้าง Dashboard มากๆ เพราะมันมีฟีเจอร์ที่ช่วยให้การพัฒนาเร็วขึ้น เช่น

✅ Server-side Rendering (SSR) – โหลดข้อมูลแบบเร็วจี๋ 🚀
✅ Static Site Generation (SSG) – ลดโหลดเซิร์ฟเวอร์และเพิ่มความเร็ว
✅ API Routes – จัดการข้อมูลจาก Backend ได้ในตัว
✅ การรองรับ Tailwind CSS, MUI, Ant Design – ทำ UI ได้ง่ายขึ้น

🛠️ เริ่มต้นโปรเจกต์ Dashboard ด้วย Next.js

1️⃣ ติดตั้ง Next.js

ถ้ายังไม่มีโปรเจกต์ Next.js ให้สร้างใหม่ก่อน

npx create-next-app@latest my-dashboard
cd my-dashboard
npm install

หรือถ้าใช้ Yarn

yarn create next-app my-dashboard
cd my-dashboard
yarn install

2️⃣ ติดตั้ง UI Library (Tailwind CSS หรือ MUI)

เราจะใช้ Tailwind CSS เพราะมันเบาและทำให้ดีไซน์ง่าย

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

แล้วเพิ่ม Tailwind ลงในไฟล์ tailwind.config.js

module.exports = {
  content: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [],
};

จากนั้นใส่ Tailwind ลงใน styles/globals.css

@tailwind base;
@tailwind components;
@tailwind utilities;


🎨 สร้าง Layout หลักของ Dashboard

ปกติ Dashboard จะมี

✅ Sidebar
✅ Navbar
✅ Content Area

เราจะสร้าง Layout หลักที่ใช้ทั่วแอป

1️⃣ สร้างไฟล์ components/Layout.js

import Sidebar from './Sidebar';
import Navbar from './Navbar';

export default function Layout({ children }) {
  return (
    <div className="flex h-screen">
      <Sidebar />
      <div className="flex flex-col flex-1">
        <Navbar />
        <main className="p-4">{children}</main>
      </div>
    </div>
  );
}

2️⃣ สร้าง Sidebar (components/Sidebar.js)

import Link from 'next/link';

export default function Sidebar() {
  return (
    <div className="w-64 bg-gray-800 text-white h-screen p-5">
      <h2 className="text-xl font-bold mb-5">Dashboard</h2>
      <ul>
        <li className="mb-2">
          <Link href="/" className="block p-2 hover:bg-gray-700 rounded">🏠 หน้าหลัก</Link>
        </li>
        <li className="mb-2">
          <Link href="/analytics" className="block p-2 hover:bg-gray-700 rounded">📊 Analytics</Link>
        </li>
        <li className="mb-2">
          <Link href="/settings" className="block p-2 hover:bg-gray-700 rounded">⚙️ Settings</Link>
        </li>
      </ul>
    </div>
  );
}

3️⃣ สร้าง Navbar (components/Navbar.js)

export default function Navbar() {
  return (
    <div className="bg-white shadow-md p-4 flex justify-between">
      <h1 className="text-lg font-bold">Dashboard</h1>
      <div>👤 User</div>
    </div>
  );
}


4️⃣ ใช้ Layout ในหน้า pages/_app.js

import Layout from '../components/Layout';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

export default MyApp;


📊 สร้างหน้า Dashboard พร้อมกราฟ

ใน Dashboard จริงๆ มักจะมี กราฟ และ ตารางข้อมูล เราจะใช้ Recharts เพื่อแสดงกราฟ

1️⃣ ติดตั้ง Recharts

npm install recharts


2️⃣ สร้างหน้า pages/index.js

import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';

const data = [
  { month: 'Jan', sales: 4000 },
  { month: 'Feb', sales: 3000 },
  { month: 'Mar', sales: 5000 },
  { month: 'Apr', sales: 7000 },
];

export default function Dashboard() {
  return (
    <div>
      <h1 className="text-2xl font-bold mb-4">📈 สถิติยอดขาย</h1>
      <div className="bg-white p-4 shadow-md">
        <ResponsiveContainer width="100%" height={300}>
          <LineChart data={data}>
            <XAxis dataKey="month" />
            <YAxis />
            <Tooltip />
            <Line type="monotone" dataKey="sales" stroke="#8884d8" strokeWidth={2} />
          </LineChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
}


📌 เพิ่มตารางข้อมูล

เราจะใช้ TanStack Table เพื่อแสดงข้อมูลในรูปแบบตาราง

1️⃣ ติดตั้ง TanStack Table

npm install @tanstack/react-table

2️⃣ เพิ่มตารางใน pages/index.js

import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';

const data = [
  { id: 1, name: 'John Doe', role: 'Admin' },
  { id: 2, name: 'Jane Smith', role: 'Editor' },
];

const columns = [
  { accessorKey: 'id', header: 'ID' },
  { accessorKey: 'name', header: 'ชื่อ' },
  { accessorKey: 'role', header: 'บทบาท' },
];

export default function Dashboard() {
  const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel() });

  return (
    <div>
      <h1 className="text-2xl font-bold mb-4">👥 ผู้ใช้งาน</h1>
      <table className="border-collapse border border-gray-300 w-full">
        <thead>
          {table.getHeaderGroups().map((headerGroup) => (
            <tr key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <th key={header.id} className="border p-2 bg-gray-100">
                  {flexRender(header.column.columnDef.header, header.getContext())}
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody>
          {table.getRowModel().rows.map((row) => (
            <tr key={row.id}>
              {row.getVisibleCells().map((cell) => (
                <td key={cell.id} className="border p-2">
                  {flexRender(cell.column.columnDef.cell, cell.getContext())}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

🎯 สรุป

✅ สร้าง Dashboard UI ใน Next.js ได้ง่าย
✅ ใช้ Tailwind CSS ทำให้ UI สวยแบบไม่ต้องเขียน CSS เอง
✅ ใช้ Recharts และ TanStack Table เพื่อแสดงข้อมูลได้อย่างมืออาชีพ

พร้อมสร้าง Dashboard ของคุณเองแล้วหรือยัง?

วันอังคารที่ 1 เมษายน พ.ศ. 2568

การแสดงผลตารางใน Next.js ด้วย TanStack Table: ง่าย สวย และยืดหยุ่นสุดๆ

ถ้าคุณเคยต้องทำตารางใน React หรือ Next.js แล้วรู้สึกว่ามันยุ่งยากไปหมด ไม่ว่าจะเป็นการจัดการข้อมูล การกรอง (filtering) การเรียงลำดับ (sorting) หรือการแบ่งหน้า (pagination) วันนี้เราจะมาแนะนำ TanStack Table (หรือชื่อเดิมคือ React Table) ที่จะช่วยให้คุณสร้างตารางขั้นเทพได้แบบง่ายๆ

ทำไมต้องใช้ TanStack Table?

ในโปรเจกต์ที่ต้องแสดงข้อมูลในรูปแบบตาราง เช่น รายการคำสั่งซื้อ, รายการผู้ใช้ หรือข้อมูลสถิติต่างๆ เราต้องการฟีเจอร์พวกนี้:

✅ การจัดการข้อมูลที่ยืดหยุ่น (เช่น ใช้ API ดึงข้อมูลมาแสดง)
✅ Sorting, Filtering, และ Pagination แบบไม่ต้องเขียนเอง
✅ รองรับการใช้งานกับ Next.js และ SSR (Server-side Rendering)

TanStack Table ทำได้หมด! 🎉

ติดตั้ง TanStack Table

ก่อนอื่น เราต้องติดตั้งไลบรารีก่อน

npm install @tanstack/react-table

หรือถ้าใช้ Yarn

yarn add @tanstack/react-table


ตัวอย่างการใช้งานพื้นฐาน

มาลองสร้างตารางง่ายๆ กันก่อน โดยใช้ข้อมูลแบบ static

1. ตั้งค่าข้อมูลและคอลัมน์

const data = [
  { id: 1, name: 'John Doe', age: 28, email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', age: 32, email: 'jane@example.com' },
  { id: 3, name: 'Bob Brown', age: 24, email: 'bob@example.com' },
];

const columns = [
  { accessorKey: 'id', header: 'ID' },
  { accessorKey: 'name', header: 'ชื่อ' },
  { accessorKey: 'age', header: 'อายุ' },
  { accessorKey: 'email', header: 'อีเมล' },
];

อธิบาย:

  • data คือข้อมูลที่เราจะเอามาแสดง
  • columns กำหนดโครงสร้างของตาราง ใช้ accessorKey เพื่อระบุคีย์ของข้อมูล


2. ใช้ TanStack Table เพื่อแสดงตาราง

import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';

export default function MyTable() {
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <table border="1">
      <thead>
        {table.getHeaderGroups().map((headerGroup) => (
          <tr key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <th key={header.id}>{flexRender(header.column.columnDef.header, header.getContext())}</th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody>
        {table.getRowModel().rows.map((row) => (
          <tr key={row.id}>
            {row.getVisibleCells().map((cell) => (
              <td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

สรุปโค้ด:

  • useReactTable() ใช้สร้างตารางจาก data และ columns
  • getCoreRowModel() ใช้เพื่อจัดการโครงสร้างของข้อมูล
  • flexRender() ช่วยให้เราสามารถเรนเดอร์ค่าที่กำหนดใน columns ได้


เพิ่ม Sorting (เรียงลำดับ)

ถ้าอยากให้ตารางสามารถเรียงลำดับ (sorting) ได้ ให้เพิ่ม getSortedRowModel()

import { useReactTable, getCoreRowModel, getSortedRowModel, flexRender } from '@tanstack/react-table';

export default function MyTable() {
  const [sorting, setSorting] = React.useState([]);
 
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    onSortingChange: setSorting,
    state: { sorting },
  });

  return (
    <table border="1">
      <thead>
        {table.getHeaderGroups().map((headerGroup) => (
          <tr key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <th key={header.id} onClick={() => header.column.getToggleSortingHandler()?.()}>
                {flexRender(header.column.columnDef.header, header.getContext())}
                {header.column.getIsSorted() === 'asc' ? ' 🔼' : header.column.getIsSorted() === 'desc' ? ' 🔽' : ''}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody>
        {table.getRowModel().rows.map((row) => (
          <tr key={row.id}>
            {row.getVisibleCells().map((cell) => (
              <td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

ตอนนี้เราสามารถคลิกที่หัวตารางเพื่อเรียงข้อมูลได้แล้ว! 🎉


เพิ่ม Pagination (แบ่งหน้า)

ถ้าข้อมูลเยอะๆ เราอาจต้องการ pagination เพื่อให้ผู้ใช้สามารถเลื่อนดูหน้าอื่นๆ ได้

import { useReactTable, getCoreRowModel, getPaginationRowModel, flexRender } from '@tanstack/react-table';

export default function MyTable() {
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
  });

  return (
    <div>
      <table border="1">
        <thead>
          {table.getHeaderGroups().map((headerGroup) => (
            <tr key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <th key={header.id}>{flexRender(header.column.columnDef.header, header.getContext())}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody>
          {table.getRowModel().rows.map((row) => (
            <tr key={row.id}>
              {row.getVisibleCells().map((cell) => (
                <td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
      <div>
        <button onClick={() => table.previousPage()} disabled={!table.getCanPreviousPage()}>
          ก่อนหน้า
        </button>
        <span> หน้า {table.getState().pagination.pageIndex + 1} </span>
        <button onClick={() => table.nextPage()} disabled={!table.getCanNextPage()}>
          ถัดไป
        </button>
      </div>
    </div>
  );
}


สรุป

✅ TanStack Table ช่วยให้สร้างตารางใน Next.js ได้ง่ายและยืดหยุ่น
✅ รองรับ Sorting, Pagination, Filtering
✅ ทำงานได้ดีทั้ง Client-side และ Server-side Rendering

ถ้าคุณต้องการตารางที่เร็วและยืดหยุ่น TanStack Table คือตัวเลือกที่ดีสุด! 

วันจันทร์ที่ 31 มีนาคม พ.ศ. 2568

การจัดการฟอร์มใน Next.js ด้วย React Hook Form: ใช้ง่าย ประหยัดแรง

ถ้าพูดถึงการจัดการฟอร์มใน React หรือ Next.js หลายคนคงเคยเจอปัญหาปวดหัวกับการจัดการ state, validation, และการ submit ข้อมูลกันใช่ไหม? วันนี้เราจะมาทำความรู้จักกับ React Hook Form ซึ่งเป็นหนึ่งในไลบรารีจัดการฟอร์มที่ดีที่สุดสำหรับ React และ Next.js ทำให้ชีวิตนักพัฒนาง่ายขึ้นเยอะ!

ทำไมต้องใช้ React Hook Form?

โดยปกติ ถ้าเราจัดการฟอร์มใน React ด้วย useState() เราจะต้องสร้าง state แยกกันตามฟิลด์ของฟอร์ม เช่น

const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');

แล้วทุกครั้งที่มีการเปลี่ยนค่าฟิลด์ เราต้องใช้ onChange มาจับข้อมูลอีก

<input type="text" value={name} onChange={(e) => setName(e.target.value)} />

มันใช้ได้ก็จริง แต่มันเยอะและยุ่งยาก!

React Hook Form (RHF) ช่วยลดความยุ่งยากนี้ ด้วยการทำให้ฟอร์มเป็นแบบ uncontrolled ซึ่งหมายความว่า ไม่ต้องใช้ useState() คุมค่าฟิลด์แบบ manual แต่ให้ React ทำงานร่วมกับ DOM โดยตรง

ติดตั้ง React Hook Form

ก่อนอื่น ต้องติดตั้ง React Hook Form ก่อน

npm install react-hook-form

หรือถ้าใช้ Yarn

yarn add react-hook-form


ใช้ React Hook Form ใน Next.js

มาดูโค้ดตัวอย่างง่ายๆ ของการใช้งาน React Hook Form ใน Next.js

สร้างฟอร์มแบบง่าย

import { useForm } from 'react-hook-form';

export default function MyForm() {
  const { register, handleSubmit } = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name')} placeholder="ชื่อ" />
      <input {...register('email')} type="email" placeholder="อีเมล" />
      <button type="submit">ส่ง</button>
    </form>
  );
}

อธิบายโค้ด:

  • useForm() คือฟังก์ชันหลักที่ใช้ดึง API ต่างๆ
  • register() ใช้สำหรับเชื่อมโยงอินพุตฟอร์มกับ React Hook Form
  • handleSubmit(onSubmit) ใช้จัดการการส่งฟอร์ม
  • data ที่ได้จาก onSubmit() จะเป็นอ็อบเจ็กต์ที่รวมค่าทั้งหมดในฟอร์ม


การเพิ่ม Validation

ถ้าไม่อยากให้ผู้ใช้กรอกมั่วๆ ก็ต้องเพิ่ม Validation Rules เข้าไป โดยใช้ register()

import { useForm } from 'react-hook-form';

export default function MyForm() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name', { required: 'ต้องกรอกชื่อ' })} placeholder="ชื่อ" />
      {errors.name && <p>{errors.name.message}</p>}

      <input {...register('email', { required: 'ต้องกรอกอีเมล', pattern: { value: /\S+@\S+\.\S+/, message: 'รูปแบบอีเมลไม่ถูกต้อง' } })} placeholder="อีเมล" />
      {errors.email && <p>{errors.email.message}</p>}

      <button type="submit">ส่ง</button>
    </form>
  );
}

สิ่งที่เพิ่มเข้ามา:

  • ใช้ errors เพื่อตรวจจับข้อผิดพลาดในแต่ละฟิลด์
  • ถ้ามี error จะแสดงข้อความแจ้งเตือนใต้ input


การใช้ Default Values

บางครั้งเราอาจต้องกำหนดค่าตั้งต้นให้ฟอร์ม เช่น กรณีแก้ไขข้อมูลผู้ใช้

const { register, handleSubmit } = useForm({
  defaultValues: {
    name: 'John Doe',
    email: 'john@example.com',
  },
});


ใช้ Controller กับ React Hook Form

ถ้าเราต้องใช้ React Component ของบุคคลที่สาม (เช่น React Select หรือ DatePicker) ที่ไม่รองรับ register() โดยตรง เราต้องใช้ Controller

import { useForm, Controller } from 'react-hook-form';
import Select from 'react-select';

export default function MyForm() {
  const { control, handleSubmit } = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="gender"
        control={control}
        render={({ field }) => <Select {...field} options={[{ label: 'ชาย', value: 'male' }, { label: 'หญิง', value: 'female' }]} />}
      />
      <button type="submit">ส่ง</button>
    </form>
  );
}

ใช้งานร่วมกับ Next.js API Routes

ถ้าเราต้องการส่งข้อมูลไปที่ API ใน Next.js สามารถทำแบบนี้

const onSubmit = async (data) => {
  const response = await fetch('/api/submit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  });
  const result = await response.json();
  console.log(result);
};

ฝั่ง API Route (/pages/api/submit.js)

export default function handler(req, res) {
  if (req.method === 'POST') {
    res.status(200).json({ message: 'ฟอร์มถูกส่งแล้ว!', data: req.body });
  } else {
    res.status(405).json({ message: 'Method Not Allowed' });
  }
}

สรุป

React Hook Form เป็นตัวช่วยที่ทำให้การจัดการฟอร์มใน Next.js ง่ายขึ้น ลดโค้ดที่ต้องเขียน และรองรับ validation แบบ built-in

  • ใช้งานง่าย – ใช้ register() เชื่อมโยงฟิลด์ได้เลย
  • ไม่ต้องใช้ useState() แยกฟิลด์ – ประหยัดโค้ด
  • รองรับ validation ในตัว – กำหนดเงื่อนไขได้ง่าย
  • ทำงานเร็วกว่าโซลูชันอื่นๆ เช่น Formik

ถ้าคุณต้องการจัดการฟอร์มใน Next.js React Hook Form คือคำตอบ!

วันอาทิตย์ที่ 30 มีนาคม พ.ศ. 2568

การใช้ Zustand หรือ Redux ใน Next.js: อะไรดีกว่ากัน?

ถ้าพูดถึงการจัดการ state ใน Next.js เชื่อว่าหลายคนต้องเคยลังเลระหว่าง Zustand กับ Redux แน่นอน เพราะทั้งสองตัวนี้ได้รับความนิยมมากและมีแนวทางการทำงานที่แตกต่างกัน วันนี้เราจะมาคุยกันแบบบ้านๆ ไม่เน้นทฤษฎีเยอะ แต่เน้นให้เข้าใจง่าย ว่าควรเลือกใช้ตัวไหนดีสำหรับโปรเจกต์ของคุณ

ทำไมต้องจัดการ State ใน Next.js?

Next.js เป็น React Framework ที่ช่วยให้เราสร้างเว็บแอปพลิเคชันได้เร็วและดีขึ้น แต่ถึงจะเทพแค่ไหน Next.js ก็ยังมีปัญหาเรื่องการจัดการ state ที่เราต้องคิดหนัก โดยเฉพาะเมื่อเว็บของเรามีหลายหน้า (multi-page) หรือมีข้อมูลที่แชร์กันระหว่างคอมโพเนนต์หลายตัว

ในกรณีที่ state ของเราซับซ้อนขึ้น การใช้ useState() หรือ useContext() อาจจะไม่พอแล้ว เช่น

  • มีหลายคอมโพเนนต์ต้องใช้ข้อมูลร่วมกัน
  • ต้องเก็บสถานะของผู้ใช้ที่ล็อกอิน
  • ต้องดึงข้อมูลจาก API แล้วแชร์ให้ทุกหน้าใช้

ถึงจุดนี้แหละ ที่พวก State Management Library อย่าง Zustand และ Redux โผล่มาช่วยชีวิตเรา

Redux: เจ้าพ่อ State Management

จุดเด่นของ Redux

Redux เป็น state container ระดับตำนานที่อยู่กับ React มานาน มันใช้ single source of truth (เก็บ state ไว้ที่เดียว) และเปลี่ยนค่า state ด้วย action และ reducer

สิ่งที่ทำให้ Redux เจ๋งคือ

  • Predictable State – ทุกการเปลี่ยนแปลงของ state ถูกควบคุมโดย action และ reducer ทำให้ debug ง่าย
  • DevTools สุดเทพ – มี Redux DevTools ให้ตรวจสอบทุกการเปลี่ยนแปลงของ state ได้แบบ real-time
  • Ecosystem ใหญ่โต – มี middleware อย่าง Redux Thunk หรือ Redux Saga ช่วยให้จัดการ asynchronous action ได้ง่ายขึ้น


จุดด้อยของ Redux

  • โค้ดยาว – Redux ต้องสร้าง action, reducer และ dispatch ซึ่งทำให้โค้ดยืดยาว ถ้าทำผิดที่เดียวอาจล้มทั้งระบบ
  • ต้องใช้ boilerplate เยอะ – แค่จะอัพเดท state ต้องผ่านหลายขั้นตอน เช่น สร้าง action → dispatch action → reducer → update store
  • Learning Curve สูง – สำหรับมือใหม่ Redux อาจทำให้ปวดหัว เพราะต้องเข้าใจโครงสร้างหลายอย่าง



Zustand: เบา สั้น และเร็ว

จุดเด่นของ Zustand

Zustand เป็น state management ที่เบาและง่ายกว่า Redux มันใช้แนวคิดของ flux pattern แต่ไม่ต้องมี action หรือ reducer ให้วุ่นวาย

สิ่งที่ทำให้ Zustand น่าสนใจคือ

  • API ใช้ง่าย – ไม่ต้องมี action หรือ reducer แค่สร้าง store แล้วใช้ได้เลย
  • ไม่มี boilerplate – Zustand ใช้ฟังก์ชันเดียวสร้าง state ได้ทันที
  • ใช้งานร่วมกับ Server Components ได้ดี – ทำให้เหมาะกับ Next.js ที่ใช้ App Router


จุดด้อยของ Zustand

  • ไม่มี DevTools ที่เทพเท่า Redux – ถ้าต้องการ debug อาจต้องใช้ console.log แทน
  • เหมาะกับโปรเจกต์ขนาดกลาง-เล็ก – ถ้าเป็นแอปขนาดใหญ่ Redux อาจจะควบคุม state ได้ดีกว่า





เปรียบเทียบ Redux vs Zustand

Feature Redux Zustand
โครงสร้างโค้ด ซับซ้อน ต้องมี action, reducer, store เรียบง่าย ใช้ฟังก์ชันเดียวสร้าง store
Performance อาจมี overhead สูงถ้าใช้ไม่ดี เบาและเร็วกว่า Redux
DevTools Redux DevTools ช่วย debug ได้ดี มี DevTools แต่ไม่เทพเท่า Redux
การใช้งานกับ Next.js ต้อง config เพิ่ม ใช้งานง่าย ไม่มี config ยุ่งยาก
เหมาะกับโปรเจกต์ ใหญ่และซับซ้อน เล็ก-กลาง


ควรใช้ Zustand หรือ Redux ใน Next.js?

ใช้ Redux ถ้า

✅ โปรเจกต์ของคุณ ซับซ้อน และต้องจัดการ state เยอะ
✅ ต้องการ DevTools เพื่อ debug state ได้ง่าย
✅ แอปของคุณต้องการ middleware เช่น Redux Thunk หรือ Redux Saga

ใช้ Zustand ถ้า

✅ คุณต้องการโค้ดที่ เรียบง่าย และ ไม่ต้องการ boilerplate
✅ โปรเจกต์ของคุณเป็น ขนาดเล็ก-กลาง และไม่ต้องการ state management ที่หนัก
✅ คุณใช้ Next.js App Router และต้องการ state management ที่เข้ากันได้ดี


ตัวอย่างการใช้ Redux กับ Next.js

ก่อนจะใช้ Redux กับ Next.js ต้องติดตั้งแพ็กเกจก่อน

npm install @reduxjs/toolkit react-redux

จากนั้นสร้าง store.js

import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) => { state.value += 1; },
    decrement: (state) => { state.value -= 1; },
  },
});

export const { increment, decrement } = counterSlice.actions;

export const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
});

แล้วใช้ Provider ใน _app.js หรือ layout.js

import { Provider } from 'react-redux';
import { store } from '../store';

export default function App({ Component, pageProps }) {
  return (
    <Provider store={store}>
      <Component {...pageProps} />
    </Provider>
  );
}

ดึงค่า state ไปใช้ในคอมโพเนนต์

import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from '../store';

export default function Counter() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => dispatch(increment())}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
    </div>
  );
}

ตัวอย่างการใช้ Zustand กับ Next.js

ติดตั้ง Zustand ก่อน

npm install zustand

สร้าง store.js

import { create } from 'zustand';

const useCounterStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}));

export default useCounterStore;

ใช้ในคอมโพเนนต์

import useCounterStore from '../store';

export default function Counter() {
  const { count, increment, decrement } = useCounterStore();

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
    </div>
  );
}

สรุป

  • Redux เหมาะกับโปรเจกต์ขนาดใหญ่ที่ต้องการความเป็นระบบ
  • Zustand เหมาะกับโปรเจกต์ที่ต้องการความง่ายและเร็ว
  • ถ้าคุณไม่แน่ใจ ให้ลองใช้ Zustand ก่อน ถ้ารู้สึกว่าไม่พอ ค่อยย้ายไป Redux

สุดท้ายแล้ว การเลือกเครื่องมือขึ้นอยู่กับ ความเหมาะสมของโปรเจกต์ ไม่มีกฎตายตัวว่าต้องใช้ตัวไหนเสมอไป

วันพุธที่ 26 มีนาคม พ.ศ. 2568

การใช้ Component Library ใน Next.js: เลือก Chakra UI, MUI หรือ shadcn/ui ดี?


ถ้าไม่อยากเขียน CSS เอง ให้ Component Library จัดการให้เถอะ!

การทำเว็บให้ดูดี ไม่ใช่แค่โค้ดดี แต่ต้องมี UI ที่สวยด้วย แต่การเขียน CSS เองมันก็เหนื่อยใช่ไหม? 😵‍💫 ถ้างั้นลองใช้ Component Library ที่มี UI สวยๆ ให้ใช้เลยดีกว่า

ในบทความนี้ เราจะมาแนะนำ 3 ตัวเลือกยอดนิยมสำหรับ Next.js ได้แก่ Chakra UI, MUI และ shadcn/ui พร้อมตัวอย่างโค้ดให้คุณลองใช้เลย

🚀 Component Library คืออะไร?

Component Library คือชุดของ UI Components (เช่น ปุ่ม, ฟอร์ม, การ์ด) ที่ออกแบบมาพร้อมใช้งาน ช่วยให้เรา ไม่ต้องเขียน CSS เอง และยังได้ UX ที่ดีขึ้น

✅ ทำไมต้องใช้ Component Library?

  • ลดเวลาทำงาน 👉 ไม่ต้องสร้าง UI จากศูนย์
  • รองรับ Responsive 👉 ใช้ได้ทั้งมือถือและเดสก์ท็อป
  • เข้ากันได้ดีกับ Next.js 👉 โหลดเร็ว, รองรับ SSR


Chakra UI – UI ที่ใช้ง่ายสุดๆ 😍

🔹 ข้อดีของ Chakra UI

✅ ใช้ Props-based Styling (ไม่ต้องเขียน CSS)
✅ รองรับ Dark Mode อัตโนมัติ
✅ มี Flexbox & Grid พร้อมใช้

🛠 ติดตั้ง Chakra UI

npm install @chakra-ui/react @emotion/react @emotion/styled framer-motion

🌟 ใช้ Chakra UI ใน Next.js

1️⃣ ห่อแอปด้วย <ChakraProvider>

แก้ไข pages/_app.js

import { ChakraProvider } from "@chakra-ui/react";

export default function MyApp({ Component, pageProps }) {
  return (
    <ChakraProvider>
      <Component {...pageProps} />
    </ChakraProvider>
  );
}


2️⃣ ลองใช้ปุ่มจาก Chakra UI

สร้าง pages/index.js

import { Button, Box, Text } from "@chakra-ui/react";

export default function Home() {
  return (
    <Box p={5}>
      <Text fontSize="xl">Hello Chakra UI! 👋</Text>
      <Button colorScheme="blue" mt={3}>
        Click Me
      </Button>
    </Box>
  );
}

🔥 จุดเด่น:

  • colorScheme="blue" 👉 เปลี่ยนสีปุ่มง่ายๆ
  • Box 👉 ใช้แทน <div> และมี spacing props เช่น p={5}



MUI (Material UI) – UI มาตรฐานองค์กร 🏢

🔹 ข้อดีของ MUI

✅ ดีไซน์มาตรฐาน Google Material Design
✅ คอมโพเนนต์เยอะมาก (Button, Table, Modal ฯลฯ)
✅ มี Theme System ปรับแต่งได้

🛠 ติดตั้ง MUI

npm install @mui/material @emotion/react @emotion/styled

🌟 ใช้ MUI ใน Next.js

1️⃣ ห่อแอปด้วย <ThemeProvider>

แก้ไข pages/_app.js

import { ThemeProvider, createTheme } from "@mui/material/styles";

const theme = createTheme();

export default function MyApp({ Component, pageProps }) {
  return (
    <ThemeProvider theme={theme}>
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

2️⃣ ลองใช้ปุ่มจาก MUI

สร้าง pages/index.js

import { Button, Container, Typography } from "@mui/material";

export default function Home() {
  return (
    <Container>
      <Typography variant="h4" gutterBottom>
        Welcome to MUI 🚀
      </Typography>
      <Button variant="contained" color="primary">
        Click Me
      </Button>
    </Container>
  );
}

🔥 จุดเด่น:

  • variant="contained" 👉 ปุ่มแบบพื้นหลังทึบ
  • Typography 👉 ใช้แทน <h1> หรือ <p>


shadcn/ui – UI ที่เบาและยืดหยุ่นสุดๆ 😎

🔹 ข้อดีของ shadcn/ui

✅ ใช้ Tailwind CSS (แต่งสไตล์ง่าย)
✅ ไม่มี JS Runtime (เร็วมาก)
✅ คัดลอกโค้ดมาใช้ได้เลย

🛠 ติดตั้ง shadcn/ui

npx shadcn-ui@latest init

จากนั้นเลือก "Install components" เพื่อนำคอมโพเนนต์มาใช้

🌟 ใช้ shadcn/ui ใน Next.js

1️⃣ ติดตั้ง Button

npx shadcn-ui@latest add button

2️⃣ ลองใช้ปุ่มจาก shadcn/ui

สร้าง pages/index.js

import { Button } from "@/components/ui/button";

export default function Home() {
  return (
    <div className="p-5">
      <h1 className="text-xl font-bold">Hello shadcn/ui!</h1>
      <Button className="mt-3">Click Me</Button>
    </div>
  );
}

🔥 จุดเด่น:

  • ใช้ Tailwind ได้เลย (className="text-xl")
  • ปรับแต่งสไตล์เองได้เต็มที่


🤔 สรุป: ควรเลือกตัวไหนดี?

Library เหมาะกับใคร?
Chakra UI ถ้าต้องการ Props-based Styling และใช้ง่าย
MUI ถ้าต้องการ Material Design และคอมโพเนนต์เยอะ
shadcn/ui ถ้าต้องการ UI เร็ว + ใช้ Tailwind

👉 ถ้าคุณชอบ:

  • ความง่าย + Dark Mode อัตโนมัติ 👉 Chakra UI
  • คอมโพเนนต์เยอะ + สไตล์องค์กร 👉 MUI
  • ใช้ Tailwind + เร็วที่สุด 👉 shadcn/ui


🎉 สรุป

  • Component Library ช่วยให้ทำเว็บเร็วขึ้น
  • Chakra UI ใช้ง่ายสุด ปรับแต่งสะดวก
  • MUI เหมาะกับแอปองค์กร
  • shadcn/ui เบา เร็ว ใช้ Tailwind ได้เต็มที่

ลองใช้ดู แล้วจะติดใจ! 😉

วันเสาร์ที่ 15 มีนาคม พ.ศ. 2568

การจัดการ Authentication กับฐานข้อมูล ใน Next.js

การสร้างระบบ Authentication หรือการยืนยันตัวตนในแอปพลิเคชันเว็บคือขั้นตอนที่สำคัญที่สุดขั้นตอนหนึ่งในการพัฒนาเว็บแอป เพราะไม่ว่าระบบนั้นจะเป็นระบบที่ให้ผู้ใช้ทำการสมัครสมาชิก เข้าสู่ระบบ หรือแม้แต่การเข้าถึงข้อมูลส่วนตัว การมีระบบที่สามารถจัดการ Authentication ได้ดีจะช่วยให้การใช้งานระบบมีความปลอดภัย และมั่นใจได้ว่า ผู้ใช้ที่เข้ามาจะต้องมีสิทธิ์ ในการใช้งานตามที่กำหนด

สำหรับ Next.js ซึ่งเป็น framework ที่พัฒนาโดย React, การจัดการ Authentication ถือเป็นส่วนที่สำคัญ โดยเฉพาะอย่างยิ่งเมื่อเราต้องทำการจัดการกับฐานข้อมูล เช่น MySQL, MongoDB หรือ PostgreSQL ซึ่งในบทความนี้เราจะพูดถึงวิธีการจัดการ Authentication บน Next.js ด้วยการเชื่อมต่อกับฐานข้อมูล โดยใช้เครื่องมือที่นิยมอย่าง bcrypt และ JWT (JSON Web Token) เพื่อให้ผู้ใช้สามารถลงทะเบียน เข้าสู่ระบบ และสามารถเข้าถึงข้อมูลที่มีการรักษาความปลอดภัยได้

เริ่มต้นสร้างโปรเจคใน Next.js

ก่อนที่เราจะเริ่มต้นการสร้างระบบ Authentication ด้วย Next.js เราต้องสร้างโปรเจค Next.js ขึ้นมาก่อน และติดตั้งแพ็กเกจที่จำเป็นบางตัว ซึ่งในที่นี้เราจะใช้ bcryptjs สำหรับการเข้ารหัสรหัสผ่าน, jsonwebtoken (JWT) สำหรับการสร้างและจัดการ Token, และ Prisma หรือ Sequelize สำหรับการจัดการกับฐานข้อมูล

1. สร้างโปรเจค Next.js

การสร้างโปรเจค Next.js เป็นขั้นตอนที่ง่ายมาก เพียงแค่ใช้คำสั่งต่อไปนี้ในเทอร์มินัล:

npx create-next-app@latest my-auth-app
cd my-auth-app

เมื่อสร้างโปรเจคเสร็จแล้ว ให้ทำการติดตั้ง dependencies ที่จำเป็น:

npm install bcryptjs jsonwebtoken prisma @prisma/client

2. ตั้งค่า Prisma สำหรับฐานข้อมูล


ถ้าคุณเลือกใช้ Prisma ในการจัดการฐานข้อมูลคุณต้องทำการตั้งค่า Prisma เพื่อเชื่อมต่อกับฐานข้อมูลที่คุณใช้ เช่น MySQL, PostgreSQL, หรือ SQLite ต่อไปนี้คือการตั้งค่าพื้นฐานสำหรับ Prisma:
  • สร้างไฟล์ schema.prisma ที่อยู่ในโฟลเดอร์ prisma สำหรับกำหนดโครงสร้างของฐานข้อมูล

npx prisma init


  • จากนั้นแก้ไขไฟล์ schema.prisma เพื่อกำหนด Model สำหรับผู้ใช้:

model User {
  id        Int    @id @default(autoincrement())
  email     String @unique
  password  String
  createdAt DateTime @default(now())
}


  • หลังจากที่ตั้งค่าฐานข้อมูลเสร็จแล้ว ให้ทำการ Migrate โครงสร้างฐานข้อมูล:
npx prisma migrate dev --name init

ตอนนี้คุณก็พร้อมที่จะใช้ Prisma ในการติดต่อกับฐานข้อมูลแล้ว

การลงทะเบียนผู้ใช้ (Registration)

ในการสร้างระบบการลงทะเบียนเราต้องให้ผู้ใช้กรอกข้อมูล เช่น อีเมล และ รหัสผ่าน โดยระบบจะทำการเข้ารหัสรหัสผ่านก่อนเก็บลงในฐานข้อมูล เพื่อให้ปลอดภัยจากการโจมตีต่างๆ โดยการใช้ bcryptjs ในการเข้ารหัสรหัสผ่านก่อนเก็บ

ตัวอย่างการลงทะเบียนผู้ใช้ใน Next.js API route

// pages/api/auth/register.js
import bcrypt from 'bcryptjs';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { email, password } = req.body;

    // ตรวจสอบว่าอีเมลมีอยู่ในฐานข้อมูลหรือไม่
    const existingUser = await prisma.user.findUnique({
      where: { email },
    });

    if (existingUser) {
      return res.status(400).json({ message: 'User already exists' });
    }

    // เข้ารหัสรหัสผ่านก่อนเก็บ
    const hashedPassword = await bcrypt.hash(password, 12);

    // สร้างผู้ใช้ใหม่ในฐานข้อมูล
    const newUser = await prisma.user.create({
      data: {
        email,
        password: hashedPassword,
      },
    });

    return res.status(201).json(newUser);
  } else {
    res.status(405).json({ message: 'Method not allowed' });
  }
}

ในโค้ดนี้เราทำการตรวจสอบว่าอีเมลของผู้ใช้ที่กรอกมีอยู่ในฐานข้อมูลหรือไม่ ถ้ามีระบบจะแจ้งว่าผู้ใช้นั้นมีอยู่แล้ว แต่ถ้าไม่มีก็จะทำการเข้ารหัสรหัสผ่านและสร้างผู้ใช้ใหม่ในฐานข้อมูล

การล็อกอินผู้ใช้ (Login)

เมื่อผู้ใช้ทำการล็อกอิน เราต้องตรวจสอบว่าอีเมลและรหัสผ่านที่กรอกเข้ามาถูกต้องหรือไม่ โดยการเปรียบเทียบรหัสผ่านที่กรอกกับรหัสผ่านที่ถูกเข้ารหัสไว้ในฐานข้อมูล จากนั้น ถ้าถูกต้อง เราจะสร้าง JWT (JSON Web Token) เพื่อใช้ในการยืนยันตัวตนของผู้ใช้ในคำขอต่อไป

ตัวอย่างการล็อกอินใน Next.js API route

// pages/api/auth/login.js
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { email, password } = req.body;

    // ค้นหาผู้ใช้ในฐานข้อมูล
    const user = await prisma.user.findUnique({
      where: { email },
    });

    if (!user) {
      return res.status(400).json({ message: 'User not found' });
    }

    // เปรียบเทียบรหัสผ่าน
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      return res.status(400).json({ message: 'Invalid password' });
    }

    // สร้าง JWT Token
    const token = jwt.sign({ userId: user.id }, 'your_jwt_secret', {
      expiresIn: '1h',
    });

    return res.status(200).json({ token });
  } else {
    res.status(405).json({ message: 'Method not allowed' });
  }
}

ในโค้ดนี้:

  1. ระบบจะค้นหาผู้ใช้จาก อีเมล ที่ผู้ใช้กรอก
  2. ถ้าพบผู้ใช้, ระบบจะทำการเปรียบเทียบ รหัสผ่านที่กรอก กับ รหัสผ่านที่เข้ารหัส ในฐานข้อมูล
  3. ถ้ารหัสผ่านถูกต้อง, ระบบจะสร้าง JWT Token และส่งกลับไปให้ผู้ใช้


การใช้งาน Token ในการยืนยันตัวตน

หลังจากที่ผู้ใช้ล็อกอินสำเร็จและได้รับ JWT Token, ผู้ใช้จะต้องส่ง Token นี้กลับมาในคำขอถัดไป เพื่อให้ระบบสามารถยืนยันตัวตนของผู้ใช้ได้

ตัวอย่างการป้องกัน API ด้วย JWT

// pages/api/protected.js
import jwt from 'jsonwebtoken';

export default function handler(req, res) {
  const token = req.headers['authorization']?.split(' ')[1];

  if (!token) {
    return res.status(401).json({ message: 'No token provided' });
  }

  try {
    const decoded = jwt.verify(token, 'your_jwt_secret');
    res.status(200).json({ message: 'This is a protected route', userId: decoded.userId });
  } catch (error) {
    res.status(401).json({ message: 'Invalid or expired token' });
  }
}

ในตัวอย่างนี้, ระบบจะตรวจสอบว่า JWT Token ที่ส่งมาพร้อมกับคำขอเป็น Token ที่ถูกต้อง หรือไม่ ถ้าถูกต้อง ระบบจะอนุญาตให้เข้าถึงข้อมูลที่ต้องการได้

สรุป

การจัดการ Authentication ใน Next.js เป็นกระบวนการที่ไม่ซับซ้อนและสามารถทำได้อย่างมีประสิทธิภาพ โดยใช้เครื่องมือที่ได้รับความนิยม เช่น bcryptjs สำหรับการเข้ารหัสรหัสผ่าน และ JWT สำหรับการสร้างและตรวจสอบ Token ซึ่งช่วยให้ระบบของเรามีความปลอดภัยและยืดหยุ่น

การใช้ Prisma ในการเชื่อมต่อฐานข้อมูลก็ทำให้การจัดการข้อมูลผู้ใช้มีความสะดวกและสามารถขยายได้ตามต้องการ โดยทั้งหมดนี้จะทำให้การสร้างระบบ Authentication ใน Next.js เป็นไปอย่างราบรื่นและปลอดภัย

วันศุกร์ที่ 14 มีนาคม พ.ศ. 2568

วิธีสร้าง GraphQL API ด้วย Next.js

ในยุคของการพัฒนาเว็บแอปพลิเคชัน, การเลือกใช้ GraphQL เป็น API ในการจัดการข้อมูลนั้นกำลังได้รับความนิยมมากขึ้นเรื่อยๆ เพราะความยืดหยุ่นและประสิทธิภาพในการดึงข้อมูลที่เป็นประโยชน์ต่อทั้งฝั่งเซิร์ฟเวอร์และไคลเอนต์ อย่างไรก็ตาม, เมื่อเราพูดถึงการสร้าง GraphQL API ใน Next.js, หลายคนอาจจะรู้สึกว่าเป็นเรื่องที่ยากและซับซ้อน เพราะเราต้องทำงานกับ GraphQL และทำความเข้าใจกับวิธีการตั้งค่าและการเชื่อมต่อกับฐานข้อมูล แต่จริงๆ แล้วการสร้าง GraphQL API ใน Next.js นั้นไม่ยากอย่างที่คิด!

ในบทความนี้, เราจะมาพูดถึงวิธีการ สร้าง GraphQL API ด้วย Next.js ซึ่งจะช่วยให้คุณสามารถสร้าง API ที่มีประสิทธิภาพและมีความยืดหยุ่นสูงในการจัดการข้อมูลจากฐานข้อมูล รวมถึงการใช้งานในแอปพลิเคชันที่ซับซ้อนได้อย่างง่ายดาย

ทำไมต้องใช้ GraphQL?

ก่อนที่จะเริ่มสร้าง GraphQL API, มาทำความเข้าใจกันก่อนว่า ทำไม GraphQL ถึงเป็นตัวเลือกที่ดี สำหรับการพัฒนา API:

  1. ดึงข้อมูลตามที่ต้องการ (Query-based): GraphQL ช่วยให้คุณสามารถดึงข้อมูลจากเซิร์ฟเวอร์ได้เฉพาะส่วนที่คุณต้องการ ซึ่งช่วยลดการขอข้อมูลที่ไม่จำเป็นและเพิ่มประสิทธิภาพ
  2. การเรียกข้อมูลหลายๆ ชุดในคำขอเดียว (Multiple Resources): คุณสามารถดึงข้อมูลจากหลายๆ แหล่งในคำขอเดียว ซึ่งช่วยลดจำนวนคำขอที่ต้องทำไปยังเซิร์ฟเวอร์
  3. การทำงานกับข้อมูลที่ซับซ้อน: GraphQL ทำให้การจัดการข้อมูลที่มีความซับซ้อน (เช่น ความสัมพันธ์ระหว่างตารางในฐานข้อมูล) ง่ายขึ้น
  4. การใช้งานที่ยืดหยุ่นและปรับขนาดได้ดี: GraphQL สามารถปรับแต่งให้เหมาะสมกับขนาดและความซับซ้อนของแอปพลิเคชันได้ง่าย


ขั้นตอนการสร้าง GraphQL API ด้วย Next.js

1. การติดตั้งเครื่องมือที่จำเป็น

ก่อนที่เราจะเริ่มสร้าง GraphQL API, เราต้องติดตั้งเครื่องมือและไลบรารีที่จำเป็นในการทำงานกับ GraphQL ใน Next.js ก่อน โดยใช้คำสั่ง:

npx create-next-app@latest my-next-graphql-app
cd my-next-graphql-app

หลังจากที่สร้างโปรเจกต์เสร็จแล้ว, เราต้องติดตั้งไลบรารีที่ช่วยในการทำงานกับ GraphQL โดยใช้คำสั่ง:

npm install apollo-server-micro graphql

  • apollo-server-micro คือไลบรารีสำหรับการสร้าง GraphQL API ที่ทำงานร่วมกับ Next.js ได้ดี
  • graphql เป็นไลบรารีหลักสำหรับการทำงานกับ GraphQL ใน Node.js


2. การตั้งค่า Apollo Server ใน Next.js

ในขั้นตอนนี้, เราจะตั้งค่า Apollo Server เพื่อให้สามารถรับคำขอ GraphQL จากลูกค้าได้ โดยการใช้ Apollo Server Micro ที่เหมาะสำหรับการทำงานในสภาพแวดล้อม serverless อย่าง Next.js

สร้างไฟล์ pages/api/graphql.js:

import { ApolloServer, gql } from 'apollo-server-micro';

// กำหนด Schema ของ GraphQL
const typeDefs = gql`
  type Query {
    hello: String
  }
`;

// กำหนด Resolvers สำหรับการดึงข้อมูล
const resolvers = {
  Query: {
    hello: () => {
      return 'Hello, world!';
    },
  },
};

// สร้าง Apollo Server
const apolloServer = new ApolloServer({
  typeDefs,
  resolvers,
});

// เปิดใช้งาน Apollo Server
const startServer = apolloServer.start();

export default async function handler(req, res) {
  await startServer;
  return apolloServer.createHandler({
    path: '/api/graphql',
  })(req, res);
}

export const config = {
  api: {
    bodyParser: false,
  },
};

ในตัวอย่างนี้, เรากำหนด GraphQL Schema โดยใช้ typeDefs ซึ่งในที่นี้มี Query hello ที่ส่งกลับข้อความ "Hello, world!". เรากำหนด Resolvers ที่ใช้ในการดึงข้อมูลจาก GraphQL ซึ่งในที่นี้จะส่งกลับข้อความที่เรากำหนดไว้

3. การทดสอบ API ด้วย GraphQL Playground

ในตอนนี้, เราสามารถเปิดโปรเจกต์ของเราและทดสอบ GraphQL API ผ่าน GraphQL Playground หรือเครื่องมืออื่นๆ ที่รองรับ GraphQL

หลังจากที่คุณเริ่มต้นเซิร์ฟเวอร์ Next.js แล้ว (โดยการรันคำสั่ง npm run dev), ไปที่ http://localhost:3000/api/graphql ในเบราว์เซอร์ของคุณเพื่อเข้าถึง GraphQL Playground ที่คุณสามารถทดสอบคำขอ GraphQL ได้

ตัวอย่างคำขอ GraphQL:

query {
  hello
}

ผลลัพธ์ที่ได้จะเป็น:

{
  "data": {
    "hello": "Hello, world!"
  }
}

4. การเชื่อมต่อ GraphQL กับฐานข้อมูล

ต่อไปเราจะเชื่อมต่อ GraphQL API กับฐานข้อมูลเพื่อให้สามารถดึงข้อมูลจากฐานข้อมูลได้ ตัวอย่างนี้เราจะใช้ Prisma ORM สำหรับการเชื่อมต่อกับฐานข้อมูล MySQL

ติดตั้ง Prisma:

npm install prisma @prisma/client

จากนั้น, ตั้งค่าฐานข้อมูลของเราในไฟล์ prisma/schema.prisma:

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

เมื่อเราได้ตั้งค่า prisma/schema.prisma แล้ว, ให้ใช้คำสั่งนี้เพื่อสร้าง Prisma Client:

npx prisma generate


5. การแก้ไข GraphQL Schema และ Resolvers สำหรับฐานข้อมูล

ตอนนี้เราจะสร้าง GraphQL schema และ resolvers สำหรับการดึงข้อมูลจากฐานข้อมูล

อัปเดต pages/api/graphql.js:

import { ApolloServer, gql } from 'apollo-server-micro';
import prisma from '../../lib/prisma'; // เชื่อมต่อกับ Prisma Client

// กำหนด GraphQL Schema สำหรับการดึงข้อมูลผู้ใช้
const typeDefs = gql`
  type User {
    id: Int
    name: String
    email: String
  }

  type Query {
    users: [User]
  }
`;

// สร้าง Resolver สำหรับการดึงข้อมูลผู้ใช้จากฐานข้อมูล
const resolvers = {
  Query: {
    users: async () => {
      return await prisma.user.findMany(); // ดึงข้อมูลผู้ใช้ทั้งหมดจากฐานข้อมูล
    },
  },
};

// สร้าง Apollo Server
const apolloServer = new ApolloServer({
  typeDefs,
  resolvers,
});

const startServer = apolloServer.start();

export default async function handler(req, res) {
  await startServer;
  return apolloServer.createHandler({
    path: '/api/graphql',
  })(req, res);
}

export const config = {
  api: {
    bodyParser: false,
  },
};

ในตัวอย่างนี้, เราได้เพิ่ม GraphQL Type สำหรับ User และ Query สำหรับดึงข้อมูลผู้ใช้ทั้งหมดจากฐานข้อมูล MySQL โดยใช้ Prisma

6. การทดสอบการดึงข้อมูลจากฐานข้อมูล

หลังจากที่เราได้อัปเดต GraphQL API แล้ว, เราสามารถทดสอบการดึงข้อมูลผู้ใช้จากฐานข้อมูลได้

ตัวอย่างคำขอ:

query {
  users {
    id
    name
    email
  }
}

ผลลัพธ์ที่ได้จะเป็น:

{
  "data": {
    "users": [
      {
        "id": 1,
        "name": "John Doe",
        "email": "johndoe@example.com"
      },
      {
        "id": 2,
        "name": "Jane Doe",
        "email": "janedoe@example.com"
      }
    ]
  }
}

7. การปรับปรุงและเพิ่มฟีเจอร์

หลังจากที่เราสร้าง GraphQL API ที่เชื่อมต่อกับฐานข้อมูลได้แล้ว, คุณสามารถขยาย API ของคุณเพื่อรองรับฟีเจอร์ต่างๆ เช่น การเพิ่มผู้ใช้ใหม่, การอัปเดตข้อมูล, การลบข้อมูล, และการทำงานกับข้อมูลที่มีความสัมพันธ์กัน

ตัวอย่างการเพิ่มผู้ใช้ใหม่:

const resolvers = {
  Mutation: {
    addUser: async (_, { name, email }) => {
      return await prisma.user.create({
        data: { name, email },
      });
    },
  },
};

สรุป

การสร้าง GraphQL API ด้วย Next.js นั้นไม่ยากอย่างที่คิด คุณสามารถใช้ Apollo Server ร่วมกับ Prisma และฐานข้อมูลต่างๆ เพื่อสร้าง API ที่ยืดหยุ่นและมีประสิทธิภาพ ในบทความนี้เราครอบคลุมการสร้าง GraphQL API สำหรับการดึงข้อมูลผู้ใช้จากฐานข้อมูล, และคุณยังสามารถขยายไปใช้ฟีเจอร์อื่นๆ ได้ตามต้องการ

วันพฤหัสบดีที่ 13 มีนาคม พ.ศ. 2568

วิธีสร้าง REST API ด้วย Next.js และฐานข้อมูล

ในโลกของการพัฒนาเว็บแอปพลิเคชัน, การสร้าง REST API ที่มีประสิทธิภาพและใช้งานได้ง่ายถือเป็นสิ่งสำคัญมาก โดยเฉพาะเมื่อเราต้องการให้แอปพลิเคชันของเราสามารถเชื่อมต่อกับฐานข้อมูลต่างๆ เพื่อจัดการข้อมูลเช่น ผู้ใช้, ข้อมูลสินค้า หรือบันทึกต่างๆ ในบทความนี้เราจะมาพูดถึงวิธีการ สร้าง REST API ด้วย Next.js ที่สามารถเชื่อมต่อกับฐานข้อมูลเพื่อให้คุณสามารถสร้างแอปพลิเคชันที่มีความสามารถในการจัดการข้อมูลได้ง่ายและเร็ว

ทำไมเลือกใช้ Next.js สำหรับการสร้าง REST API?

ก่อนที่เราจะไปถึงขั้นตอนการสร้าง REST API, มาทำความเข้าใจกันก่อนว่า ทำไม Next.js ถึงเป็นเครื่องมือที่ดีสำหรับการสร้าง REST API:

  1. API Routes ของ Next.js: Next.js มีฟีเจอร์ที่เรียกว่า API Routes ที่ช่วยให้คุณสามารถสร้าง API ได้ภายในโปรเจกต์เดียวกันกับแอปพลิเคชันของคุณ โดยที่ไม่จำเป็นต้องตั้งค่าเซิร์ฟเวอร์แยกต่างหาก
  2. รองรับการทำงานทั้งฝั่งเซิร์ฟเวอร์และไคลเอนต์: Next.js รองรับทั้ง Server-Side Rendering (SSR) และ Static Site Generation (SSG) แต่ยังรองรับการสร้าง API สำหรับการดึงข้อมูลจากฐานข้อมูลหรือจัดการข้อมูลได้อย่างง่ายดาย
  3. ความยืดหยุ่นสูง: คุณสามารถใช้ Next.js ร่วมกับฐานข้อมูลต่างๆ เช่น MySQL, MongoDB, PostgreSQL, หรือ Firebase ได้อย่างยืดหยุ่น
  4. การพัฒนาแบบ Full-stack: Next.js ช่วยให้คุณสามารถสร้างแอปพลิเคชัน Full-stack ได้ในโปรเจกต์เดียว ทำให้การจัดการโค้ดและการบำรุงรักษาง่ายขึ้น


ขั้นตอนการสร้าง REST API ด้วย Next.js และฐานข้อมูล

1. การเตรียมเครื่องมือและติดตั้ง

ก่อนที่จะเริ่มสร้าง REST API ด้วย Next.js, เราต้องเตรียมเครื่องมือและติดตั้งโปรเจกต์ Next.js ก่อน โดยใช้คำสั่ง:

npx create-next-app@latest my-next-api-app
cd my-next-api-app

เมื่อโปรเจกต์ Next.js ถูกสร้างขึ้นแล้ว, เราจะติดตั้งไลบรารีที่จำเป็นในการเชื่อมต่อกับฐานข้อมูล

การติดตั้งไลบรารีฐานข้อมูล

ในที่นี้, เราจะใช้ Prisma ORM สำหรับการเชื่อมต่อกับฐานข้อมูล ซึ่งช่วยให้การจัดการข้อมูลในฐานข้อมูลเป็นไปอย่างสะดวกและมีประสิทธิภาพ

ติดตั้ง Prisma และ Database Client:

npm install prisma @prisma/client

จากนั้น, เราต้องตั้งค่าฐานข้อมูลของเราในไฟล์ schema.prisma โดยการเชื่อมต่อกับฐานข้อมูลที่เราใช้ เช่น PostgreSQL, MySQL, หรือ SQLite

ตัวอย่างการตั้งค่า Prisma สำหรับ MySQL:

ในไฟล์ prisma/schema.prisma:

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

จากนั้น, คุณสามารถใช้คำสั่งนี้เพื่อสร้าง Prisma Client:

npx prisma generate


2. การเชื่อมต่อฐานข้อมูลใน Next.js

ในขั้นตอนนี้, เราจะสร้างไฟล์สำหรับการเชื่อมต่อกับฐานข้อมูล โดยใช้ Prisma Client ที่เราติดตั้งไว้แล้ว

สร้างไฟล์ lib/prisma.js:

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default prisma;

ในไฟล์นี้, เราจะสร้าง Prisma Client ที่เชื่อมต่อกับฐานข้อมูลของเรา และจะนำไปใช้ใน API Routes ใน Next.js

3. การสร้าง REST API Route สำหรับดึงข้อมูล

Next.js รองรับการสร้าง API Routes ที่สามารถใช้ในการดึงข้อมูลจากฐานข้อมูลได้โดยตรง ตัวอย่างการสร้าง API Route สำหรับดึงข้อมูลจากฐานข้อมูล
ตัวอย่างการสร้าง API Route สำหรับดึงข้อมูลผู้ใช้:

สร้างไฟล์ pages/api/users.js:

import prisma from '../../lib/prisma';

export default async function handler(req, res) {
  if (req.method === 'GET') {
    try {
      const users = await prisma.user.findMany();
      res.status(200).json(users);
    } catch (error) {
      res.status(500).json({ error: 'Unable to fetch users' });
    }
  }
}

ในตัวอย่างนี้, เราใช้ GET method เพื่อดึงข้อมูลผู้ใช้ทั้งหมดจากฐานข้อมูล และส่งกลับมาในรูปแบบ JSON

4. การสร้าง API Route สำหรับเพิ่มข้อมูล

เราสามารถใช้ POST method ในการเพิ่มข้อมูลใหม่เข้าไปในฐานข้อมูล ตัวอย่างการสร้าง API Route สำหรับเพิ่มผู้ใช้ใหม่:

สร้างไฟล์ pages/api/users.js:

import prisma from '../../lib/prisma';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { name, email } = req.body;

    try {
      const newUser = await prisma.user.create({
        data: {
          name,
          email,
        },
      });

      res.status(201).json(newUser);
    } catch (error) {
      res.status(500).json({ error: 'Unable to add user' });
    }
  }
}

ในตัวอย่างนี้, เมื่อได้รับคำขอ POST ที่มีข้อมูลผู้ใช้ใหม่ใน req.body, ระบบจะเพิ่มข้อมูลนี้เข้าไปในฐานข้อมูลและส่งกลับข้อมูลผู้ใช้ที่ถูกเพิ่มไปแล้ว

5. การสร้าง API Route สำหรับแก้ไขข้อมูล

เราสามารถใช้ PUT หรือ PATCH method ในการแก้ไขข้อมูลที่มีอยู่ในฐานข้อมูล ตัวอย่างการสร้าง API Route สำหรับการอัปเดตข้อมูลผู้ใช้:

// pages/api/users/[id].js
import prisma from '../../../lib/prisma';

export default async function handler(req, res) {
  const { id } = req.query;

  if (req.method === 'PUT') {
    const { name, email } = req.body;

    try {
      const updatedUser = await prisma.user.update({
        where: { id: parseInt(id) },
        data: { name, email },
      });

      res.status(200).json(updatedUser);
    } catch (error) {
      res.status(500).json({ error: 'Unable to update user' });
    }
  }
}

ในตัวอย่างนี้, เราใช้ PUT method ในการอัปเดตข้อมูลของผู้ใช้ตาม id ที่ถูกส่งมาจาก URL และทำการอัปเดตข้อมูลในฐานข้อมูล

6. การสร้าง API Route สำหรับลบข้อมูล

เราสามารถใช้ DELETE method ในการลบข้อมูลที่มีอยู่ในฐานข้อมูล ตัวอย่างการสร้าง API Route สำหรับการลบผู้ใช้:

// pages/api/users/[id].js
import prisma from '../../../lib/prisma';

export default async function handler(req, res) {
  const { id } = req.query;

  if (req.method === 'DELETE') {
    try {
      const deletedUser = await prisma.user.delete({
        where: { id: parseInt(id) },
      });

      res.status(200).json(deletedUser);
    } catch (error) {
      res.status(500).json({ error: 'Unable to delete user' });
    }
  }
}

ในตัวอย่างนี้, เราจะใช้ DELETE method ในการลบผู้ใช้ตาม id ที่ได้รับจาก URL

7. การทดสอบ API

เมื่อเราได้สร้าง REST API เสร็จเรียบร้อยแล้ว, ขั้นตอนสุดท้ายคือลองทดสอบการทำงานของ API โดยใช้เครื่องมืออย่าง Postman หรือ Insomnia เพื่อทดสอบว่า API สามารถทำงานได้ตามที่คาดหวังหรือไม่

สรุป

การสร้าง REST API ด้วย Next.js และฐานข้อมูล เป็นวิธีที่ยอดเยี่ยมในการพัฒนาเว็บแอปที่มีการจัดการข้อมูลอย่างมีประสิทธิภาพและง่ายดาย โดยการใช้ API Routes ของ Next.js และไลบรารี Prisma ช่วยให้การเชื่อมต่อและการจัดการข้อมูลในฐานข้อมูลเป็นเรื่องง่ายและสะดวก ในการสร้าง REST API ของคุณ, คุณสามารถจัดการข้อมูลต่างๆ เช่น การดึงข้อมูล, การเพิ่มข้อมูล, การอัปเดตข้อมูล, และการลบข้อมูลได้อย่างมีประสิทธิภาพ

วันพุธที่ 12 มีนาคม พ.ศ. 2568

การใช้ Redis ใน Next.js

ในยุคปัจจุบันที่เทคโนโลยีเว็บแอปพลิเคชันต้องการการทำงานที่รวดเร็วและมีประสิทธิภาพสูง, Redis เป็นหนึ่งในเครื่องมือที่ได้รับความนิยมในด้านการจัดการข้อมูลแบบ In-memory หรือการจัดเก็บข้อมูลในหน่วยความจำ (RAM) ที่ช่วยให้การเข้าถึงข้อมูลนั้นเร็วขึ้นมาก ซึ่ง Redis สามารถใช้เป็น Cache (การเก็บข้อมูลในหน่วยความจำชั่วคราว) หรือ Message Broker (ตัวกลางสำหรับการส่งข้อความระหว่างระบบ) ได้

ในบทความนี้เราจะมาพูดถึงวิธีการ ใช้ Redis ใน Next.js โดยการเชื่อมต่อ Redis กับ Next.js ช่วยให้เราสามารถเพิ่มความเร็วให้กับแอปพลิเคชัน โดยเฉพาะในด้านการจัดการการเก็บข้อมูลชั่วคราวหรือการทำงานร่วมกับระบบที่มีการเข้าถึงข้อมูลที่บ่อยครั้ง

ทำไม Redis ถึงสำคัญ?

ก่อนที่เราจะไปเรียนรู้วิธีการใช้ Redis ใน Next.js เรามาทำความเข้าใจก่อนว่า ทำไม Redis ถึงเป็นตัวเลือกที่ดี สำหรับเว็บแอปพลิเคชัน:

  1. การเก็บข้อมูลในหน่วยความจำ (In-memory storage): Redis เป็นฐานข้อมูลที่จัดเก็บข้อมูลใน RAM ซึ่งทำให้สามารถเข้าถึงข้อมูลได้รวดเร็วมากเมื่อเทียบกับฐานข้อมูลที่เก็บข้อมูลบนดิสก์
  2. เหมาะสำหรับการแคช (Caching): Redis นิยมใช้ในการเก็บข้อมูลที่ถูกใช้งานบ่อยๆ เช่น ผลลัพธ์จากการคำนวณที่มีราคาแพง หรือผลลัพธ์จากการดึงข้อมูลจากฐานข้อมูลที่ใช้เวลานาน ซึ่งสามารถเก็บไว้ใน Redis เพื่อให้สามารถดึงข้อมูลได้เร็วขึ้นในครั้งถัดไป
  3. รองรับการทำงานแบบ Pub/Sub: Redis สามารถใช้เป็นระบบ Message Broker โดยรองรับการส่งข้อความในรูปแบบ Publish/Subscribe ซึ่งช่วยให้การส่งข้อมูลระหว่างบริการต่างๆ ในแอปพลิเคชันสามารถทำได้เร็วและมีประสิทธิภาพ
  4. รองรับการทำงานหลายแอปพลิเคชัน: Redis สามารถเชื่อมต่อกับแอปพลิเคชันได้หลากหลายภาษาและเฟรมเวิร์ก รวมถึง Next.js ที่เป็นเฟรมเวิร์กที่นิยมใช้ในการพัฒนาเว็บแอป


ขั้นตอนการใช้ Redis ใน Next.js

1. การติดตั้ง Redis และไลบรารีที่จำเป็น

ก่อนที่จะเชื่อมต่อ Redis กับ Next.js, เราต้องติดตั้ง Redis และไลบรารีที่จำเป็นในการเชื่อมต่อ Redis จาก Node.js เช่น ioredis หรือ redis ซึ่งจะช่วยให้เราสามารถเชื่อมต่อ Redis ได้ง่ายๆ

การติดตั้ง Redis:

ถ้าคุณยังไม่ได้ติดตั้ง Redis บนเครื่องของคุณ, คุณสามารถติดตั้งได้ผ่านคำสั่งดังนี้ (ในกรณีใช้ MacOS):

brew install redis

หรือในกรณีของ Ubuntu:

sudo apt-get install redis-server

การติดตั้งไลบรารี Redis ใน Next.js:

ใช้คำสั่งดังนี้เพื่อทำการติดตั้งไลบรารี ioredis ซึ่งเป็นไลบรารีที่นิยมใช้ในการเชื่อมต่อ Redis ใน Node.js:

npm install ioredis

หรือถ้าคุณใช้ yarn:

yarn add ioredis

2. การตั้งค่า Redis Client

เมื่อเราได้ติดตั้งไลบรารี Redis แล้ว, ขั้นตอนต่อไปคือการตั้งค่า Redis Client สำหรับเชื่อมต่อกับ Redis instance ที่เราติดตั้งไว้

ตัวอย่างการตั้งค่า Redis Client:

// lib/redis.js
import Redis from 'ioredis';

const redis = new Redis({
  host: 'localhost', // หรือใช้ host ที่ Redis ของคุณอยู่
  port: 6379, // default Redis port
  password: '', // หาก Redis ของคุณมีการตั้งรหัสผ่าน
});

export default redis;

ในตัวอย่างนี้, เราจะใช้ ioredis ในการสร้าง Redis Client และเชื่อมต่อกับ Redis instance ที่อยู่บนเครื่องของเรา (localhost) ซึ่งสามารถตั้งค่าเพิ่มเติมได้ตามความต้องการ เช่น การใช้ password หรือการตั้งค่าการเชื่อมต่อแบบอื่นๆ

3. การใช้ Redis ใน API Routes ของ Next.js

หลังจากที่เราตั้งค่า Redis Client แล้ว, ขั้นตอนถัดไปคือการใช้ Redis ใน API Routes ของ Next.js เพื่อทำการแคชข้อมูลหรือใช้ Redis เพื่อเก็บข้อมูลชั่วคราว ตัวอย่างการใช้งาน Redis ใน API Route ของ Next.js

ตัวอย่างการใช้ Redis ใน API Route:

// pages/api/cache-data.js
import redis from '../../lib/redis';

export default async function handler(req, res) {
  if (req.method === 'GET') {
    const cachedData = await redis.get('myData'); // ดึงข้อมูลจาก Redis

    if (cachedData) {
      console.log('Cache hit');
      return res.status(200).json(JSON.parse(cachedData)); // ถ้ามีข้อมูลใน Cache ให้ส่งกลับไป
    }

    console.log('Cache miss');
    // ถ้าไม่มีข้อมูลใน Cache, เราสามารถดึงข้อมูลจากฐานข้อมูลหรือ API อื่นๆ
    const data = { name: 'John Doe', age: 30 };

    // เก็บข้อมูลใน Cache โดยใช้ Redis
    await redis.set('myData', JSON.stringify(data), 'EX', 60 * 60); // ตั้งเวลา Cache หมดอายุภายใน 1 ชั่วโมง

    return res.status(200).json(data); // ส่งข้อมูลไปยังผู้ใช้งาน
  }
}

ในตัวอย่างนี้, เราใช้ Redis เพื่อเก็บข้อมูลในหน่วยความจำและลดการเข้าถึงข้อมูลซ้ำๆ ที่เกิดจากการดึงข้อมูลจากฐานข้อมูลหรือแหล่งข้อมูลอื่นๆ โดยที่ myData จะถูกเก็บใน Redis และมีการตั้งเวลาให้หมดอายุหลังจาก 1 ชั่วโมง (EX หมายถึงเวลาหมดอายุในวินาที)

4. การใช้ Redis ในการจัดการการทำงานแบบ Session

Redis ยังสามารถใช้ในการจัดการ Session ของผู้ใช้งานในเว็บแอปพลิเคชันของเรา โดยการเก็บข้อมูลการเข้าสู่ระบบของผู้ใช้ เช่น token หรือข้อมูลการล็อกอิน

ตัวอย่างการจัดการ Session ด้วย Redis:

// pages/api/login.js
import redis from '../../lib/redis';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { username, password } = req.body;

    // ตรวจสอบข้อมูลผู้ใช้ (แค่ตัวอย่าง, ในการใช้งานจริงต้องตรวจสอบจากฐานข้อมูล)
    if (username === 'admin' && password === 'password') {
      const sessionToken = 'some-random-token';

      // เก็บ session ใน Redis
      await redis.set(`session:${sessionToken}`, JSON.stringify({ username }), 'EX', 3600); // Session หมดอายุภายใน 1 ชั่วโมง

      return res.status(200).json({ message: 'Login successful', token: sessionToken });
    } else {
      return res.status(401).json({ message: 'Invalid credentials' });
    }
  }
}

ในตัวอย่างนี้, เมื่อผู้ใช้ทำการล็อกอินสำเร็จ, เราจะสร้าง sessionToken และเก็บไว้ใน Redis ซึ่งจะหมดอายุหลังจาก 1 ชั่วโมง

5. การใช้ Redis ในการทำงานแบบ Pub/Sub

Redis ยังรองรับการทำงานในรูปแบบ Publish/Subscribe (Pub/Sub) ซึ่งช่วยให้คุณสามารถส่งข้อความจากที่หนึ่งไปยังอีกที่หนึ่งได้โดยตรงในระบบ

ตัวอย่างการใช้ Pub/Sub ใน Redis:

// pub.js (สำหรับ Publish)
import redis from './lib/redis';

export function publishMessage(channel, message) {
  redis.publish(channel, message);
}

// sub.js (สำหรับ Subscribe)
import redis from './lib/redis';

redis.subscribe('myChannel', (err, count) => {
  if (err) {
    console.error('Subscription error:', err);
  }
});

redis.on('message', (channel, message) => {
  if (channel === 'myChannel') {
    console.log('Received message:', message);
  }
});

ในตัวอย่างนี้, เราจะใช้ Redis ในการส่งข้อความจากที่หนึ่งไปยังอีกที่หนึ่งผ่าน Pub/Sub ซึ่งเป็นประโยชน์ในระบบที่ต้องการการแจ้งเตือนหรือการส่งข้อมูลระหว่างบริการต่างๆ ที่เกี่ยวข้อง

สรุป

การใช้ Redis ใน Next.js เป็นวิธีที่ยอดเยี่ยมในการเพิ่มประสิทธิภาพของแอปพลิเคชันของคุณ โดยการเก็บข้อมูลใน หน่วยความจำ ทำให้สามารถเข้าถึงข้อมูลได้เร็วขึ้น ซึ่งเหมาะสำหรับการใช้ในกรณีที่ข้อมูลมีการใช้งานบ่อยๆ หรือการจัดการข้อมูลชั่วคราว เช่น การแคชข้อมูลหรือการจัดการ session นอกจากนี้ Redis ยังสามารถใช้ในการทำงานแบบ Pub/Sub ซึ่งเป็นประโยชน์ในการสร้างระบบที่สามารถสื่อ

วันอังคารที่ 11 มีนาคม พ.ศ. 2568

การใช้ MongoDB กับ Next.js

ในโลกของการพัฒนาเว็บแอปพลิเคชันในปัจจุบัน, MongoDB เป็นฐานข้อมูลที่ได้รับความนิยมมากขึ้นเรื่อยๆ โดยเฉพาะในแอปพลิเคชันที่ต้องการการจัดการข้อมูลที่ไม่จำเป็นต้องอยู่ในโครงสร้างเชิงสัมพันธ์หรือการเก็บข้อมูลที่มีความยืดหยุ่นสูง หากคุณกำลังพัฒนาเว็บแอปพลิเคชันด้วย Next.js และต้องการฐานข้อมูล NoSQL ที่สามารถขยายตัวได้ดีและรองรับข้อมูลที่มีโครงสร้างไม่ตายตัว, MongoDB ก็เป็นตัวเลือกที่ยอดเยี่ยมสำหรับคุณ

ในบทความนี้เราจะมาทำความเข้าใจวิธีการ ใช้ MongoDB กับ Next.js โดยจะอธิบายตั้งแต่การติดตั้งการเชื่อมต่อกับ MongoDB ไปจนถึงการใช้งานฐานข้อมูลใน API Routes ของ Next.js และแนวทางการออกแบบระบบอย่างมีประสิทธิภาพ

ทำไม MongoDB ถึงเหมาะสมกับ Next.js?

1. การจัดการข้อมูลแบบ NoSQL

MongoDB เป็นฐานข้อมูลประเภท NoSQL ที่เก็บข้อมูลในรูปแบบของเอกสาร (Document) ซึ่งแตกต่างจากฐานข้อมูล SQL ที่เก็บข้อมูลในตารางแบบเชิงสัมพันธ์ (Relational Database) โดยเอกสารใน MongoDB จะเก็บข้อมูลในรูปแบบของ JSON-like หรือ BSON (Binary JSON) ที่สามารถเก็บข้อมูลในโครงสร้างที่ยืดหยุ่นได้ ซึ่งเหมาะสำหรับการพัฒนาเว็บแอปที่ต้องการการจัดเก็บข้อมูลที่ไม่ตายตัว

2. ความยืดหยุ่นในการขยายตัว

MongoDB รองรับการขยายตัวได้ง่ายและมีการจัดการข้อมูลที่สามารถทำงานได้ดีในสถานการณ์ที่ข้อมูลจำนวนมากมีการเปลี่ยนแปลงตลอดเวลา โดยที่ไม่ต้องกังวลเรื่องโครงสร้างที่คงที่

3. ทำงานได้ดีร่วมกับ Next.js

Next.js รองรับการทำงานทั้งฝั่งเซิร์ฟเวอร์และไคลเอนต์ (Client-Side & Server-Side Rendering) ซึ่งสามารถนำ MongoDB มาใช้งานร่วมกันได้อย่างลงตัว ไม่ว่าจะเป็นการจัดการข้อมูลในฝั่งเซิร์ฟเวอร์โดยใช้ API Routes หรือการดึงข้อมูลแบบ Server-Side Rendering (SSR)

ขั้นตอนการติดตั้งและการเชื่อมต่อ MongoDB กับ Next.js

1. การติดตั้ง MongoDB และไลบรารีที่จำเป็น

ก่อนอื่น, คุณจะต้องติดตั้งไลบรารีที่จำเป็นในการเชื่อมต่อ MongoDB กับ Next.js ซึ่งเราจะแนะนำการใช้ Mongoose ซึ่งเป็น ORM (Object-Relational Mapping) ที่ทำให้การทำงานกับ MongoDB ง่ายขึ้น

การติดตั้ง Mongoose สามารถทำได้โดยใช้คำสั่ง:

npm install mongoose

หรือหากใช้ yarn:

yarn add mongoose

2. การตั้งค่าการเชื่อมต่อ MongoDB

จากนั้น, เราจะสร้างไฟล์สำหรับการเชื่อมต่อกับ MongoDB ในโปรเจกต์ของเรา ในตัวอย่างนี้, เราจะสร้างไฟล์ lib/mongodb.js เพื่อจัดการการเชื่อมต่อกับฐานข้อมูล

// lib/mongodb.js
import mongoose from 'mongoose';

const MONGO_URI = 'mongodb://localhost:27017/your_database_name';

if (!MONGO_URI) {
  throw new Error('Please define the MONGO_URI environment variable');
}

let cached = global.mongoose;

if (!cached) {
  cached = global.mongoose = { conn: null, promise: null };
}

async function connectToDatabase() {
  if (cached.conn) {
    return cached.conn;
  }

  if (!cached.promise) {
    cached.promise = mongoose.connect(MONGO_URI).then((mongoose) => {
      return mongoose;
    });
  }

  cached.conn = await cached.promise;
  return cached.conn;
}

export default connectToDatabase;

ในไฟล์นี้ เราจะเชื่อมต่อกับฐานข้อมูล MongoDB โดยใช้ URI ที่คุณได้ตั้งค่าไว้ใน .env หรือในโค้ด หากคุณใช้ MongoDB Atlas ก็สามารถใช้ URI ของ Atlas ได้เช่นกัน

3. การสร้าง Model ของ MongoDB

เมื่อเชื่อมต่อกับฐานข้อมูลแล้ว, คุณต้องสร้าง Model สำหรับการทำงานกับข้อมูลใน MongoDB โดยการใช้ Mongoose เพื่อให้สามารถใช้งานข้อมูลได้อย่างง่ายดาย

ตัวอย่างการสร้าง Model ของ MongoDB:

// models/User.js
import mongoose from 'mongoose';

const UserSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true },
});

export default mongoose.models.User || mongoose.model('User', UserSchema);

ในที่นี้ เราได้สร้าง User Schema ที่ใช้เก็บข้อมูลของผู้ใช้ เช่น name และ email โดยใช้ Mongoose ที่จะช่วยให้การจัดการข้อมูลใน MongoDB เป็นไปอย่างสะดวก

4. การใช้ MongoDB ใน API Routes ของ Next.js

ตอนนี้เราได้ตั้งค่าการเชื่อมต่อกับ MongoDB และสร้าง Model เรียบร้อยแล้ว, ขั้นตอนต่อไปคือการใช้งาน MongoDB ใน API Routes ของ Next.js เพื่อทำงานกับข้อมูล เช่น การดึงข้อมูลจาก MongoDB หรือการเพิ่มข้อมูลใหม่

ตัวอย่างการดึงข้อมูลจาก MongoDB ใน API Route:

// pages/api/users.js
import connectToDatabase from '../../lib/mongodb';
import User from '../../models/User';

export default async function handler(req, res) {
  await connectToDatabase();

  if (req.method === 'GET') {
    try {
      const users = await User.find();
      res.status(200).json(users);
    } catch (error) {
      res.status(500).json({ error: 'Unable to fetch users' });
    }
  }
}

ในตัวอย่างนี้, เราจะใช้ GET เพื่อดึงข้อมูลจาก MongoDB และส่งข้อมูลในรูปแบบ JSON ไปยังผู้ใช้งาน

5. การเพิ่มข้อมูลใน MongoDB ผ่าน API Route

การเพิ่มข้อมูลใน MongoDB ก็สามารถทำได้โดยใช้ POST ใน API Route ซึ่งสามารถรับข้อมูลจาก req.body และทำการบันทึกข้อมูลไปยังฐานข้อมูลได้

// pages/api/users.js
import connectToDatabase from '../../lib/mongodb';
import User from '../../models/User';

export default async function handler(req, res) {
  await connectToDatabase();

  if (req.method === 'POST') {
    const { name, email } = req.body;

    try {
      const newUser = new User({ name, email });
      await newUser.save();
      res.status(201).json(newUser);
    } catch (error) {
      res.status(500).json({ error: 'Unable to add user' });
    }
  }
}

ในตัวอย่างนี้, เราจะใช้ POST เพื่อรับข้อมูลจาก req.body และเพิ่มผู้ใช้ใหม่เข้าไปใน MongoDB

6. การใช้ MongoDB กับ Server-Side Rendering (SSR)

หนึ่งในคุณสมบัติที่ดีของ Next.js คือการรองรับ Server-Side Rendering (SSR) ซึ่งทำให้เราสามารถดึงข้อมูลจากฐานข้อมูลมาแสดงผลบนหน้าเว็บก่อนที่หน้านั้นจะโหลดเสร็จ

ตัวอย่างการใช้งาน MongoDB ใน getServerSideProps (SSR):

// pages/index.js
import connectToDatabase from '../lib/mongodb';
import User from '../models/User';

export async function getServerSideProps() {
  await connectToDatabase();

  const users = await User.find();

  return {
    props: { users: JSON.parse(JSON.stringify(users)) },
  };
}

export default function Home({ users }) {
  return (
    <div>
      <h1>User List</h1>
      <ul>
        {users.map((user, index) => (
          <li key={index}>{user.name} - {user.email}</li>
        ))}
      </ul>
    </div>
  );
}

ในตัวอย่างนี้, เราใช้ getServerSideProps เพื่อดึงข้อมูลจาก MongoDB และส่งข้อมูลไปยังหน้าเว็บเพื่อแสดงผลในครั้งแรกที่โหลดหน้า

สรุป

การใช้ MongoDB ร่วมกับ Next.js เป็นวิธีที่ยอดเยี่ยมในการสร้างเว็บแอปที่สามารถจัดการข้อมูลได้อย่างมีประสิทธิภาพ โดย MongoDB ให้ความยืดหยุ่นในการจัดเก็บข้อมูลแบบ NoSQL และ Next.js ให้เครื่องมือในการสร้างเว็บแอปที่เร็วและรองรับการเรนเดอร์แบบ Server-Side Rendering (SSR) การเชื่อมต่อ MongoDB กับ Next.js ไม่ได้ยากเกินไปและสามารถช่วยให้คุณสร้างเว็บแอปที่มีฟีเจอร์ครบถ้วนและมีประสิทธิภาพได้

วันจันทร์ที่ 10 มีนาคม พ.ศ. 2568

การเชื่อมต่อ MySQL กับ Next.js

ในยุคปัจจุบันที่การพัฒนาเว็บแอปพลิเคชันมีความหลากหลายและต้องการการจัดการข้อมูลที่มีประสิทธิภาพมากขึ้น การใช้ฐานข้อมูลที่สามารถจัดเก็บข้อมูลได้ดีและเชื่อถือได้ยังคงเป็นสิ่งสำคัญ สำหรับแอปพลิเคชันหลายๆ ตัวที่เราใช้งานในชีวิตประจำวัน MySQL ยังคงเป็นหนึ่งในฐานข้อมูลที่ได้รับความนิยมอย่างมาก เพราะมีประสิทธิภาพสูงในการจัดการข้อมูลในรูปแบบเชิงสัมพันธ์ (Relational Database) ซึ่งสามารถตอบโจทย์การจัดเก็บข้อมูลที่ซับซ้อนได้ดี

ในบทความนี้เราจะมาเรียนรู้วิธีการ เชื่อมต่อ MySQL กับ Next.js กัน โดย Next.js เป็นเฟรมเวิร์กที่ใช้ในการพัฒนาเว็บแอปที่ทำงานได้ทั้งฝั่งเซิร์ฟเวอร์และฝั่งไคลเอนต์ และมีการรองรับการเรนเดอร์ในหลายๆ รูปแบบ เช่น Server-Side Rendering (SSR) และ Static Site Generation (SSG) ซึ่งเป็นเครื่องมือที่ยอดเยี่ยมในการพัฒนาเว็บแอป

ทำไมต้องใช้ MySQL?

ก่อนที่จะไปสู่ขั้นตอนการเชื่อมต่อ MySQL กับ Next.js เรามาทำความเข้าใจสักเล็กน้อยว่า ทำไม MySQL ถึงเป็นตัวเลือกที่ดี สำหรับแอปพลิเคชันของคุณ:

  1. การจัดการข้อมูลแบบเชิงสัมพันธ์: MySQL เป็นฐานข้อมูลที่มีความสามารถในการจัดการข้อมูลที่มีความสัมพันธ์กันได้ดี เช่น ข้อมูลในตารางลูกค้า, ออเดอร์ หรือข้อมูลที่เกี่ยวข้องกับผลิตภัณฑ์
  2. ประสิทธิภาพสูง: MySQL ถูกออกแบบมาให้สามารถรองรับการทำงานในปริมาณข้อมูลจำนวนมากได้ดี
  3. ความน่าเชื่อถือ: MySQL เป็นฐานข้อมูลที่มีความเสถียรสูง และมีการใช้งานกันอย่างแพร่หลาย โดยได้รับการพัฒนาและอัปเดตอย่างต่อเนื่อง
  4. ใช้งานง่าย: การเรียนรู้และใช้งาน MySQL ค่อนข้างง่ายเมื่อเทียบกับฐานข้อมูลประเภทอื่นๆ

ดังนั้น หากคุณกำลังพัฒนาแอปพลิเคชันที่ต้องการจัดเก็บข้อมูลที่เป็นระบบและสามารถจัดการได้อย่างมีประสิทธิภาพ MySQL เป็นตัวเลือกที่เหมาะสมมากๆ สำหรับโปรเจกต์ของคุณ

ขั้นตอนการเชื่อมต่อ MySQL กับ Next.js

1. การติดตั้ง MySQL ในโปรเจกต์

ในการเริ่มต้นใช้งาน MySQL ร่วมกับ Next.js เราจำเป็นต้องติดตั้งไลบรารีที่จะช่วยในการเชื่อมต่อกับฐานข้อมูล MySQL ก่อน โดยการใช้ไลบรารีที่ชื่อว่า mysql2 หรือ sequelize ซึ่งเป็นไลบรารีที่ช่วยให้การเชื่อมต่อและการทำงานกับฐานข้อมูล MySQL ง่ายขึ้น

การติดตั้งไลบรารี mysql2

npm install mysql2

หรือถ้าใช้ yarn:

yarn add mysql2

การติดตั้งไลบรารี sequelize (ถ้าต้องการใช้ ORM)

npm install sequelize mysql2

2. การตั้งค่าการเชื่อมต่อ MySQL

หลังจากติดตั้งไลบรารีเสร็จแล้ว เราจะต้องตั้งค่าการเชื่อมต่อ MySQL เพื่อให้สามารถเชื่อมต่อกับฐานข้อมูลได้ โดยในโปรเจกต์ Next.js เราจะทำการตั้งค่าในไฟล์แยกต่างหากเพื่อจัดการการเชื่อมต่อให้เรียบร้อย

ตัวอย่างการเชื่อมต่อด้วย mysql2:

// lib/db.js
import mysql from 'mysql2';

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'your_database_name'
});

connection.connect((err) => {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }
  console.log('connected as id ' + connection.threadId);
});

export default connection;

ในตัวอย่างนี้ เราจะสร้างการเชื่อมต่อไปยังฐานข้อมูล MySQL ด้วยไลบรารี mysql2 โดยการตั้งค่า เช่น host, user, password, และ database ที่ใช้ในการเชื่อมต่อ

ตัวอย่างการเชื่อมต่อด้วย sequelize:

// lib/sequelize.js
import { Sequelize } from 'sequelize';

const sequelize = new Sequelize('your_database_name', 'root', 'password', {
  host: 'localhost',
  dialect: 'mysql',
});

export default sequelize;

การใช้ sequelize จะช่วยให้เราเขียนโค้ดในรูปแบบของ ORM (Object-Relational Mapping) ซึ่งทำให้เราสามารถใช้ JavaScript ในการจัดการข้อมูลในฐานข้อมูลได้ง่ายขึ้น

3. การใช้ฐานข้อมูลใน API Routes ของ Next.js

หนึ่งในคุณสมบัติที่ดีของ Next.js คือการรองรับ API Routes ซึ่งช่วยให้เราสามารถสร้าง API ภายในแอปได้ง่ายๆ โดยไม่ต้องตั้งค่าเซิร์ฟเวอร์เพิ่มเติม การใช้ API Routes นี้ เราสามารถเชื่อมต่อกับ MySQL เพื่อดึงข้อมูล หรือบันทึกข้อมูลได้

ตัวอย่างการดึงข้อมูลจาก MySQL ใน API Route:

// pages/api/users.js
import db from '../../lib/db';  // ถ้าใช้ mysql2
// หรือ
// import sequelize from '../../lib/sequelize';  // ถ้าใช้ sequelize

export default async function handler(req, res) {
  if (req.method === 'GET') {
    db.query('SELECT * FROM users', (err, results) => {
      if (err) {
        res.status(500).json({ error: 'Database query failed' });
        return;
      }
      res.status(200).json(results);
    });
  }
}

ในตัวอย่างนี้เราจะดึงข้อมูลจากตาราง users ในฐานข้อมูล MySQL และส่งข้อมูลกลับไปยังผู้ใช้งานในรูปแบบ JSON

ถ้าใช้ sequelize:

// pages/api/users.js
import sequelize from '../../lib/sequelize';
import { User } from '../../models'; // สมมติว่าเรามีโมเดล User

export default async function handler(req, res) {
  if (req.method === 'GET') {
    try {
      const users = await User.findAll();
      res.status(200).json(users);
    } catch (err) {
      res.status(500).json({ error: 'Database query failed' });
    }
  }
}

ในตัวอย่างนี้ เราจะใช้ Sequelize ORM เพื่อดึงข้อมูลจากฐานข้อมูล ซึ่งจะทำให้การเขียนโค้ดง่ายขึ้น และสามารถจัดการกับข้อมูลได้สะดวกมากกว่า

4. การเพิ่มข้อมูลใน MySQL ผ่าน API Route

การเพิ่มข้อมูลในฐานข้อมูลก็สามารถทำได้ง่ายๆ ผ่าน API Route ของ Next.js โดยเราสามารถรับข้อมูลจาก request body และใช้คำสั่ง SQL หรือ ORM เพื่อเพิ่มข้อมูลได้

ตัวอย่างการเพิ่มข้อมูลใน MySQL:

// pages/api/users.js
import db from '../../lib/db';  // ถ้าใช้ mysql2

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { name, email } = req.body;

    db.query('INSERT INTO users (name, email) VALUES (?, ?)', [name, email], (err, results) => {
      if (err) {
        res.status(500).json({ error: 'Database insertion failed' });
        return;
      }
      res.status(200).json({ message: 'User added successfully' });
    });
  }
}

ถ้าใช้ sequelize:

// pages/api/users.js
import sequelize from '../../lib/sequelize';
import { User } from '../../models'; // สมมติว่าเรามีโมเดล User

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { name, email } = req.body;

    try {
      const newUser = await User.create({ name, email });
      res.status(200).json(newUser);
    } catch (err) {
      res.status(500).json({ error: 'Database insertion failed' });
    }
  }
}

5. การใช้งาน MySQL ในการสร้างแอปพลิเคชันที่มีฟีเจอร์มากขึ้น

จากขั้นตอนเบื้องต้นที่เราได้เรียนรู้การเชื่อมต่อ MySQL กับ Next.js แล้ว คุณสามารถนำความรู้เหล่านี้ไปใช้ในการสร้างแอปพลิเคชันที่มีฟีเจอร์หลากหลาย เช่น ระบบการจัดการผู้ใช้ (User Management System), การจัดการคำสั่งซื้อ (Order Management System), หรือการเก็บข้อมูลสำหรับแอปพลิเคชันที่ต้องการข้อมูลที่มีความสัมพันธ์กัน

สรุป

การเชื่อมต่อ MySQL กับ Next.js ไม่ได้ยากเกินไป และสามารถช่วยให้คุณสร้างเว็บแอปที่มีความสามารถในการจัดการข้อมูลได้อย่างมีประสิทธิภาพ การใช้ MySQL ร่วมกับ Next.js ทำให้คุณสามารถพัฒนาเว็บแอปที่รวดเร็วและสามารถทำงานได้ทั้งในฝั่งเซิร์ฟเวอร์และฝั่งไคลเอนต์ นอกจากนี้ยังสามารถใช้ฟีเจอร์ต่างๆ ของ MySQL เพื่อให้แอปของคุณมีประสิทธิภาพมากยิ่งขึ้น

การใช้ Image Optimization ใน Next.js: โหลดไว SEO ดี ประหยัดแบนด์วิธ!

เคยเจอปัญหาเว็บโหลดช้าเพราะรูปภาพขนาดใหญ่หรือเปล่า? 📷 ถ้าใช่ Next.js มีฟีเจอร์ Image Optimization ที่ช่วยให้รูปภาพโหลดเร็วขึ้น อัตโนมัติ ไม...