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

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

การเรียก API ภายใน Next.js อย่างมีประสิทธิภาพ

การเรียก API เป็นเรื่องที่ทุกเว็บแอปต้องทำ ไม่ว่าจะเป็นการดึงข้อมูลจาก Backend, Third-party APIs หรือแม้แต่ API ภายในแอปเอง แต่จะเรียกยังไงให้เร็ว แรง และไม่ทำให้เว็บช้า?

Next.js มีหลายวิธีในการเรียก API ไม่ว่าจะเป็น Server-side fetching, Client-side fetching, Static generation, หรือแม้แต่ ใช้ API Routes ภายในตัวเอง วันนี้เราจะมาเจาะลึกกันว่าควรเลือกใช้วิธีไหนในแต่ละสถานการณ์ เพื่อให้แอปของคุณทำงานเร็วที่สุด 🚀

🔍 วิธีเรียก API ใน Next.js

ใน Next.js เราสามารถเรียก API ได้หลัก ๆ 3 วิธี

  1. Client-side fetching → ใช้ fetch หรือ SWR ใน React Component
  2. Server-side fetching (SSR) → ใช้ getServerSideProps เพื่อโหลดข้อมูลตอนโหลดหน้า
  3. Static generation (SSG) → ใช้ getStaticProps โหลดข้อมูลล่วงหน้า

แต่ละวิธีมีข้อดีข้อเสียต่างกัน เดี๋ยวมาดูรายละเอียดกันเลย!

🎯 1. การเรียก API ฝั่ง Client (Client-side Fetching)

ถ้าข้อมูลที่เราต้องการโหลด ไม่จำเป็นต้องมาเร็วก่อนหน้าแสดงผล เช่น

  •     รายการโพสต์
  •     คอมเมนต์
  •     ข้อมูลที่อัปเดตแบบเรียลไทม์

การใช้ Client-side Fetching จะช่วยให้หน้าเว็บโหลดเร็วขึ้นเพราะมันจะดึงข้อมูลหลังจากโหลดหน้าเสร็จ

🔹 วิธีใช้ fetch กับ useEffect (พื้นฐาน)

import { useEffect, useState } from 'react'

export default function Posts() {
  const [posts, setPosts] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch('/api/posts')
      .then((res) => res.json())
      .then((data) => {
        setPosts(data)
        setLoading(false)
      })
  }, [])

  if (loading) return <p>กำลังโหลดโพสต์...</p>

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

แต่ปัญหาของวิธีนี้คือ ทุกครั้งที่เข้าเพจ มันจะ fetch API ใหม่เสมอ ซึ่งอาจทำให้โหลดข้อมูลซ้ำ ๆ แบบไม่จำเป็น

🔹 วิธีใช้ SWR ให้โหลดเร็วขึ้น

ถ้าอยากให้ ดึงข้อมูลแล้วแคชไว้ ไม่ต้องโหลดใหม่ตลอด SWR เป็นตัวช่วยที่ดี

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then((res) => res.json())

export default function Posts() {
  const { data, error } = useSWR('/api/posts', fetcher)

  if (error) return <p>เกิดข้อผิดพลาด</p>
  if (!data) return <p>กำลังโหลด...</p>

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ SWR ดียังไง?

  •     แคชข้อมูลไว้ ไม่ต้องโหลดใหม่ทุกครั้ง
  •     อัปเดตข้อมูลอัตโนมัติเมื่อมีการเปลี่ยนแปลง
  •     โหลดเร็วขึ้นเพราะดึงจากแคชก่อน แล้วอัปเดตภายหลัง

ถ้าเป็น ข้อมูลที่ต้องอัปเดตบ่อย เช่น Dashboard หรือ Notifications ควรใช้ SWR จะดีที่สุด!

⚡️ 2. การเรียก API ฝั่งเซิร์ฟเวอร์ (SSR)

บางครั้งเราต้องโหลดข้อมูล ก่อนแสดงผลหน้าเว็บ เช่น

  • ข้อมูลผู้ใช้ที่ล็อกอิน
  • สินค้าในตะกร้า
  • รายการสั่งซื้อ

ในกรณีนี้ getServerSideProps เป็นทางเลือกที่ดี เพราะมันจะดึงข้อมูลบนเซิร์ฟเวอร์ก่อนแล้วส่งไปให้หน้าเว็บ

🔹 วิธีใช้ getServerSideProps

export async function getServerSideProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data } }
}

export default function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ ข้อดีของ SSR

  • โหลดข้อมูลก่อนแสดงผล → ผู้ใช้เห็นข้อมูลทันที
  • เหมาะกับข้อมูลที่เปลี่ยนแปลงบ่อย เช่น ข้อมูลผู้ใช้
  • รองรับ SEO ดีกว่า Client-side Fetching

❌ ข้อเสีย

  • โหลดช้ากว่าเพราะต้องรอ API ตอบก่อนแสดงผล
  • ถ้า API ช้าจะทำให้หน้าเว็บช้าไปด้วย

ถ้าเป็น API ที่ต้องใช้ข้อมูลสดใหม่ทุกครั้ง เช่น ข้อมูลผู้ใช้ที่ล็อกอินอยู่ getServerSideProps คือทางเลือกที่ดี

🏎 3. โหลด API ล่วงหน้าด้วย Static Generation (SSG)

ถ้าข้อมูลที่เราต้องการ เปลี่ยนแปลงไม่บ่อย เช่น

  • บทความ
  • รายชื่อสินค้า
  • รายการหมวดหมู่

เราสามารถใช้ getStaticProps โหลดข้อมูลตอน Build เวลา Deploy แล้วหน้าเว็บจะโหลดเร็วมาก 🚀

🔹 วิธีใช้ getStaticProps

export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data } }
}

export default function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ ข้อดีของ SSG

  • โหลดเร็วมาก เพราะไม่ต้องรอ API ตอนเปิดหน้า
  • เหมาะกับหน้าเว็บที่ข้อมูลเปลี่ยนไม่บ่อย

❌ ข้อเสีย

  • ข้อมูลจะไม่อัปเดตจนกว่าจะ Build ใหม่

ถ้าต้องการให้ SSG รีเฟรชข้อมูลได้เอง สามารถใช้ revalidate เช่น

export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data }, revalidate: 60 } // รีเฟรชทุก 60 วินาที
}

🔥 สรุป: ควรใช้วิธีไหน?

วิธี ใช้เมื่อ ข้อดี ข้อเสีย
Client-side Fetching ข้อมูลเปลี่ยนบ่อย (Dashboard, คอมเมนต์) โหลดเร็ว ไม่ต้องรอ API ไม่ดีต่อ SEO
Server-side Fetching (SSR) ข้อมูลต้องอัปเดตทุกครั้ง เช่น ผู้ใช้ล็อกอิน โหลดก่อนแสดงผล ดีต่อ SEO ช้ากว่า Client-side
Static Generation (SSG) ข้อมูลเปลี่ยนไม่บ่อย เช่น บทความ โหลดเร็วมาก ไม่อัปเดตอัตโนมัติ

เลือกให้เหมาะสมกับโปรเจกต์ของคุณ แล้วเว็บจะทั้งเร็วและมีประสิทธิภาพ! 🚀

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

การใช้ API Routes เพื่อสร้าง Backend ใน Next.js

ถ้าพูดถึง Next.js หลายคนคงนึกถึง Frontend Framework ที่ช่วยพัฒนาเว็บได้เร็วและแรง แต่รู้หรือเปล่าว่า Next.js ก็มี Backend ในตัว ด้วย?

ใช่แล้ว! Next.js มาพร้อมกับ API Routes ที่ให้เราสร้าง Backend API ได้ง่าย ๆ โดยไม่ต้องใช้ Express, NestJS หรือพวก Backend Framework อื่น ๆ

ในบทความนี้ เราจะมาทำความรู้จัก API Routes ใน Next.js ว่ามันคืออะไร ใช้งานยังไง และมีประโยชน์อะไรบ้าง ถ้าพร้อมแล้วไปลุยกันเลย! 🚀

🤔 API Routes คืออะไร?

API Routes คือฟีเจอร์ของ Next.js ที่ให้เราสร้าง REST API ได้โดยตรงในโปรเจกต์ Next.js เอง โดยไม่ต้องเซ็ตเซิร์ฟเวอร์แยก

📌 ข้อดีของ API Routes

✅ ไม่ต้องใช้ Backend แยก – Next.js จัดการให้
✅ ใช้ JavaScript/TypeScript ล้วน ๆ – ไม่ต้องเรียนรู้ภาษาใหม่
✅ รองรับ Serverless Functions – ทำงานบน Vercel, AWS Lambda, Firebase Functions ได้เลย
✅ ใช้ร่วมกับ Frontend ง่าย – อยู่ในโปรเจกต์เดียวกัน

ถ้าเทียบกับการใช้ Node.js + Express ที่ต้องเซ็ตเซิร์ฟเวอร์เอง API Routes ของ Next.js จะง่ายกว่าเยอะ!

🛠 สร้าง API Routes แรกของคุณ

ใน Next.js ไฟล์ API Routes จะอยู่ใน /pages/api/ เช่น

📂 โครงสร้างโฟลเดอร์

my-next-app/
 ├── pages/
 │   ├── index.js
 │   ├── about.js
 │   ├── api/       <-- โฟลเดอร์ API
 │   │   ├── hello.js   <-- ไฟล์ API Route
 │   │   ├── users.js
 │   │   ├── posts.js

ลองสร้างไฟล์ /pages/api/hello.js แล้วใส่โค้ดนี้ลงไป

export default function handler(req, res) {
  res.status(200).json({ message: 'สวัสดีจาก API Routes!' })
}

✨ ลองรันเซิร์ฟเวอร์

npm run dev
# หรือ
yarn dev

แล้วเข้า http://localhost:3000/api/hello จะได้ JSON แบบนี้

{
  "message": "สวัสดีจาก API Routes!"
}

ง่ายมากใช่ไหม? ไม่ต้องติดตั้ง Express หรือเซ็ต Server อะไรให้ยุ่งยากเลย!

🚀 การใช้ HTTP Methods (GET, POST, PUT, DELETE)

API Routes รองรับทุก HTTP Method เช่น GET, POST, PUT, DELETE โดยเช็คจาก req.method

✨ ตัวอย่าง API รองรับหลาย Method

ไฟล์ /pages/api/users.js

export default function handler(req, res) {
  if (req.method === 'GET') {
    res.status(200).json({ users: ['Alice', 'Bob', 'Charlie'] })
  } else if (req.method === 'POST') {
    res.status(201).json({ message: 'สร้างผู้ใช้ใหม่เรียบร้อย!' })
  } else {
    res.status(405).json({ error: 'Method ไม่รองรับ' })
  }
}

🔹 GET → ดึงข้อมูลผู้ใช้
🔹 POST → สร้างผู้ใช้ใหม่
🔹 อื่น ๆ → ส่ง 405 Method Not Allowed

ลองยิง API ดู! 🚀

curl -X GET http://localhost:3000/api/users
curl -X POST http://localhost:3000/api/users


🔄 อ่านค่า Query Parameters

ถ้าต้องการดึงค่าจาก Query String (เช่น /api/user?id=123) เราสามารถใช้ req.query ได้เลย

ไฟล์ /pages/api/user.js

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

  if (!id) {
    return res.status(400).json({ error: 'กรุณาระบุ id' })
  }

  res.status(200).json({ user: { id, name: 'John Doe' } })
}

✨ ทดสอบ API

curl http://localhost:3000/api/user?id=456

📌 output

{
  "user": { "id": "456", "name": "John Doe" }
}


📬 รับข้อมูลจาก Body (POST Method)

ถ้าต้องการรับข้อมูลจาก Body ของ Request เช่นเวลาส่งฟอร์มหรือ JSON Data เราสามารถใช้ req.body ได้เลย

ไฟล์ /pages/api/login.js

export default function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method ไม่รองรับ' })
  }

  const { username, password } = req.body

  if (username === 'admin' && password === '1234') {
    res.status(200).json({ message: 'เข้าสู่ระบบสำเร็จ!' })
  } else {
    res.status(401).json({ error: 'ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง' })
  }
}

✨ ทดสอบ API

curl -X POST http://localhost:3000/api/login -H "Content-Type: application/json" -d '{"username": "admin", "password": "1234"}'

📌 output

{
  "message": "เข้าสู่ระบบสำเร็จ!"
}

🔒 ใช้ Middleware กับ API Routes

ถ้าต้องการตรวจสอบ JWT Token หรือทำ Authentication ก่อนเข้าถึง API สามารถใช้ Middleware ได้ง่าย ๆ

ไฟล์ /pages/api/secure.js

export default function handler(req, res) {
  const { authorization } = req.headers

  if (!authorization || authorization !== 'Bearer mysecrettoken') {
    return res.status(403).json({ error: 'ไม่ได้รับอนุญาต' })
  }

  res.status(200).json({ message: 'เข้าถึงข้อมูลสำเร็จ!' })
}

✨ ทดสอบ API (ล้มเหลว)

curl http://localhost:3000/api/secure

📌 output

{
  "error": "ไม่ได้รับอนุญาต"
}

✨ ทดสอบ API (สำเร็จ)

curl -H "Authorization: Bearer mysecrettoken" http://localhost:3000/api/secure

📌 output

{
  "message": "เข้าถึงข้อมูลสำเร็จ!"
}

🎯 สรุป

API Routes เป็นฟีเจอร์ที่ช่วยให้เราสร้าง Backend API ใน Next.js ได้ง่าย ๆ โดยไม่ต้องติดตั้งเซิร์ฟเวอร์แยก เหมาะกับการทำงานแบบ Fullstack ที่ต้องการพัฒนา Frontend และ Backend ไปพร้อมกัน

📌 จุดเด่นของ API Routes

✅ ใช้งานง่าย – ไม่ต้องเซ็ตเซิร์ฟเวอร์เอง
✅ รองรับ HTTP Methods (GET, POST, PUT, DELETE)
✅ ใช้ Query Parameters และ Request Body ได้
✅ รองรับ Middleware เช่น Authentication

ถ้าคุณใช้ Next.js อยู่แล้ว ลองใช้ API Routes ดู แล้วจะรู้ว่ามัน โคตรสะดวก! 🚀

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

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