- Next.js คืออะไร? + มาหัดเขียนเว็บด้วย Next.js กันดีกว่า
- ตอนที่ 1 - Hello Next.js เริ่มสร้างโปรเจ็ค
- ตอนที่ 2 - สร้าง Page และการ navigate ระหว่าง Pages
- ตอนที่ 3 - การจัดการ Assets, Metadata และ CSS
- ตอนที่ 4 - เรื่องของ Pre Rendering
- ตอนที่ 5 - Data Fetching และการดึงข้อมูลจาก API
- ตอนที่ 6 - การทำ Dynamic Routes
- ตอนที่ 7 - API Routes การทำ API ด้วย Next.js
ตอนที่ 7 - API Routes การทำ API ด้วย Next.js
เขียนวันที่ : Jul 16, 2022
API Routes
ใน Next.js เราสามารถทำตัวเป็น Backend APIs ได้เลย โดยที่ไม่ต้องมี Server เพิ่ม (ปกติอาจจะต้องมี Node.js server อีกตัว) โดยเพียงแค่สร้างโฟลเดอร์ api
ไว้ภายใน pages
ก็พอครับ โดยไฟล์ /pages/api
จะ map กับ /api/*
ตามชื่อไฟล์ที่เราตั้ง เช่น
pages/api/posts.js
- เพื่อเอาไว้ get posts ทั้งหมด โดยเรียกด้วยGET /api/posts
pages/api/posts/[id].js
- เพื่อดึง post ตาม id มาแสดง โดยเรียกด้วยGET /api/posts/:id
ซึ่งจริงๆแล้ว ไม่ได้เฉพาะแค่ GET
สามารถรับ HTTP Methodds อื่นๆ ได้ด้วยเช่นกัน
ตัวอย่าง ผมสร้างไฟล์ api/user.js
ขึ้นมา ให้มัน return JSON กลับไป ปกติ
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
ซึ่งถ้าเราดูมันก็จะคล้ายๆการเขียนด้วย Express.js ครับ
const express = require('express')
const app = express()
const handler = (req, res) => {
res.status(200).json({ name: 'John Doe'})
}
app.get('/api/user', handler)
โดยที่ req
และ res
ก็จะเป็น Client Request และ Server Response
เช่น เราจะเช็คว่า request ที่ส่งมาที่ API ของ Next.js เราเนี่ย เป็น HTTP Method อะไร ก็เช็คแบบนี้
export default function handler(req, res) {
if (req.method === 'POST') {
// post
} else if (req.method === 'PATCH') {
// patch
} else {
// others
}
}
หรือจะเช็ค POST body/payload ก็ได้เช่นกัน
export default function handler(req, res) {
const { username, email } = req.body;
// your logic
}
- API โดย default แล้ว จะเป็นแบบ same-origin คือเฉพาะ domain เดียวกันที่เรียก API ได้ ไม่สามารถทำ API และให้ domain อื่นๆ มาเรียกใช้ได้ (แต่สามารถ custom ได้ผ่าน CORS Middleware)
- API Routes ไม่สามารถใช้กับ
next export
ได้ - ข้อดีของ API Route คือ เอาไว้ทำ API เวลาที่ต้องใช้ token ต่อกับ 3rd Party (ถ้าเรียกจาก Client ก็จะเห็น token ใช่มั้ยครับ)
Dynamic API Routes
ตัว API Routes ก็รองรับ Dynamic Routes แบบเดียวกับ Page component เลย คือตั้งชื่อไฟล์เช่น pages/api/posts/[id].js
export default function handler(req, res) {
const { id } = req.query
res.json({
ok: true,
id,
})
}
ทีนี้ เวลาเราเรียก /api/posts/*
มันก็จะได้ response เป็น id ที่แตกต่างกัน
นอกจากนี้ Dynamic API Routes ก็สามารถทำ catch all api routes ได้เหมือนกับ Page Component เช่นกัน คือกำหนดไฟล์ไว้แบบนี้ [...id].js
มันก็จะ match ทั้ง /api/post/a
, /api/post/a/b
, /api/post/a/b/c
ไปเรื่อยๆ
API Middlewares
Next API Route สามารถใช้ middleware ได้เหมือนกับ Express.js ทุกๆ API Route เราสามารถ export config
object ได้ ตัวอย่าง
export const config = {
api: {
bodyParser: {
sizeLimit: '1mb',
},
},
}
ตัวอย่าง เช่น การใช้ CORS Middleware
ติดตั้ง CORS
yarn add cors
ตัวอย่าง allow method GET
และ HEAD
import Cors from 'cors'
// Initializing the cors middleware
const cors = Cors({
methods: ['GET', 'HEAD'],
})
// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(req, res, fn) {
return new Promise((resolve, reject) => {
fn(req, res, (result) => {
if (result instanceof Error) {
return reject(result)
}
return resolve(result)
})
})
}
async function handler(req, res) {
// Run the middleware
await runMiddleware(req, res, cors)
// Rest of the API logic
res.json({ message: 'Hello Everyone!' })
}
export default handler
อ่านเพิ่มเติม - Next.js - API Middlewares
ลองสร้าง API Posts
ลองสร้าง API สำหรับ provide ข้อมูล blog posts สร้างไฟล์ชื่อ pages/api/posts.js
และ pages/api/posts/[id].js
ซึ่งจริงๆแล้ว การที่สร้าง index กับ id ที่เป็น dynamic id เราสามารถสร้างได้ 2 แบบครับคือ
/api/posts.js
และ /api/posts/[id].js
หรือ
/api/posts/index.js
และ /api/posts/[id].js
โดยไฟล์ pages/api/posts.js
มีข้อมูลแบบนี้
const posts = [
{
id: 1,
title: 'Post #1',
content: 'lorem ipsum 1',
},
{
id: 2,
title: 'Post #2',
content: 'lorem ipsum 2',
},
]
export default function handler(req, res) {
res.status(200).json(posts)
}
ส่วนไฟล์ pages/api/posts/[id].js
เป็นแบบนี้
export default function handler(req, res) {
const {
query: { id },
method,
} = req
const { title } = req.body
switch (method) {
case 'GET':
res.status(200).json({ id, title: `Post #${id}` })
break
case 'PUT':
res.status(200).json({ id, title: title || `Post #${id}` })
break
default:
res.setHeader('Allow', ['GET', 'PUT'])
res.status(405).end(`Method ${method} Not Allowed`)
}
}
โดยที่เรามี logic เช็คว่า รองรับแค่ GET
และ PUT
ถ้ามีการเรียก POST
มา ก็จะ return 405 กลับไป พร้อมข้อความ Method POST Not Allowed
ทดสอบเรียก http://localhost:3000/api/posts และ http://localhost:3000/api/posts/1 ดูครับ
จบแล้วสำหรับเรื่อง API Routes ซึ่งหลักๆ การเรียนรู้ Next.js เบื้องต้น ก็มีประมาณเท่านี้ครับ ตอนต่อไป จะเป็นหัวข้อเสริม คือเรื่องของการใช้ Next.js ร่วมกับ TypeScript ครับ
คำถาม
- ถ้าเราจะ fetch api จาก 3rd party ระหว่างใช้ API Routes กับ
getServerSideProps
ต่างกันมั้ย? - ข้อดีของการใช้ API Routes คืออะไร?
- มี use cases ไหนบ้าง ที่น่าใช้ API Routes แทนที่จะใช้
getStaticProps
หรือgetServerSideProps