การเรียก 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 วิธี
- Client-side fetching → ใช้ fetch หรือ SWR ใน React Component
- Server-side fetching (SSR) → ใช้ getServerSideProps เพื่อโหลดข้อมูลตอนโหลดหน้า
- 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) | ข้อมูลเปลี่ยนไม่บ่อย เช่น บทความ | โหลดเร็วมาก | ไม่อัปเดตอัตโนมัติ |
เลือกให้เหมาะสมกับโปรเจกต์ของคุณ แล้วเว็บจะทั้งเร็วและมีประสิทธิภาพ! 🚀