โหมดมืด
บทที่ 0 — API คืออะไร และทำไมต้อง "ดี"
ก่อนอ่าน — ต้องรู้อะไรมาก่อน?
บทนี้ถือว่าคุณ:
- เคยใช้ web app / mobile app — รู้ว่า frontend (ฝั่งหน้าจอ) คุยกับ backend (ฝั่งเซิร์ฟเวอร์) ผ่าน "อะไรบางอย่าง"
- เข้าใจคำว่า "HTTP", "JSON", "URL" คร่าว ๆ
- เขียน code ตัวเล็ก ๆ ได้ (อย่างน้อย CRUD app)
ยังไม่ชัวร์เรื่อง HTTP/JSON/URL? อ่าน primer สั้น ๆ ก่อนได้:
- HTTP (เอช-ที-ที-พี) = โปรโตคอลที่ browser ใช้คุยกับ server — request (ขอ) แล้วได้ response (ตอบ) กลับมา · MDN: HTTP overview
- JSON (เจ-ซัน) = format ข้อความสำหรับส่งข้อมูล โครงสร้างเป็น key-value
{"name":"Anna","age":25}· MDN: JSON- URL (ยู-อาร์-แอล) = ที่อยู่ของ resource บนเว็บ เช่น
https://api.example.com/users/1· MDN: What is a URL?
หลังจบบท คุณจะ:
- เข้าใจว่า API คืออะไร + ทำไมต้องดี
- รู้จัก API styles (REST, GraphQL, gRPC, WebSocket, SSE)
- เลือก style ที่เหมาะกับ use case
- เข้าใจคำศัพท์พื้นฐาน + HTTP method + status code
1. API คืออะไร — เริ่มจาก analogy
ลองนึกภาพร้านอาหาร:
API = "เมนู + พนักงานเสิร์ฟ" ระหว่าง 2 ฝั่ง — ลูกค้าไม่ต้องเข้าครัวเอง
นิยามให้ตรง
API = Application Programming Interface — "หน้าบ้าน" ที่ให้คนอื่นเรียกใช้ระบบเรา
ทุกครั้งที่:
- เปิด app → app เรียก API
- มือถือสั่ง Uber → app เรียก API ของ Uber
- ที่เว็บคุณกดปุ่ม → frontend เรียก API ของ backend
- ChatGPT ตอบ → app เรียก API ของ OpenAI
API = "สัญญา" ระหว่าง 2 ฝั่ง — frontend เรียกได้ + backend ตอบยังไง
2. ทำไม API ที่ "ดี" สำคัญ
ลองดูตัวอย่างก่อน:
❌ API ห่วย
GET /getAllUsers ← ใช้ verb (ผิด REST)
GET /user_list?status=1 ← ตั้งชื่อไม่สม่ำเสมอ (inconsistent) + magic number (เลขลอย ๆ ที่ไม่รู้ความหมาย)
GET /api/v2/users ← v2 มี endpoint นี้ vs v3 ไม่มี (ลืม version)
GET /search?q=foo ← return 200 OK + body `{"error":"not found"}` (HTTP บอกสำเร็จ แต่ body บอก error — contract ไม่ตรง)
POST /users/delete/1 ← method ไม่ตรงกับ action
GET /users → return: "id,name,age\n1,Anna,25" ← CSV ใน JSON?!หลังใช้ 6 เดือน — frontend dev ทุกคนเกลียด → bug เยอะ → maintain ยาก
✅ API ดี
GET /api/v1/users ← noun + plural + versioning
GET /api/v1/users?status=active ← descriptive query
GET /api/v1/users/123 ← resource by id
POST /api/v1/users ← create
PATCH /api/v1/users/123 ← partial update
DELETE /api/v1/users/123 ← delete
GET /api/v1/users/123/orders ← nested resource
Response:
200 → { "data": {...}, "meta": {...} }
404 → { "error": { "code": "NOT_FOUND", "message": "User not found" } }อ่านครั้งเดียวเข้าใจ — ใช้งานง่าย — debug ง่าย — extend ได้
Cost of Bad API
API ดี ≠ optional — เพราะ:
- Internal API (frontend ↔ backend ของเรา):
เปลี่ยนได้ แต่ frontend ต้องแก้ทุกที่
- Public API (เปิดให้คนภายนอกใช้):
เปลี่ยน = ทุก app ที่ใช้ break
ลูกค้าโกรธ + อาจฟ้องร้องลองจินตนาการ — Stripe เปลี่ยน /charges endpoint break → ทุก app ที่รับเงินทั่วโลกพัง 😱
กฎทอง: ออกแบบ API ให้ดีตั้งแต่แรก — เพราะ change ทีหลัง = expensive
3. API ใน Modern Web Architecture (ปี 2026)
ลองดูภาพ — แต่ละชั้นใช้ API คุยกัน:
BFF (Backend for Frontend) = backend ตัวเล็กที่ทำมาเฉพาะ frontend แต่ละแบบ (เว็บ/มือถือ) เพื่อรวม/ปรับข้อมูลให้เหมาะกับฝั่งนั้น ๆ
Microservices = สถาปัตยกรรมที่แยกระบบใหญ่ออกเป็น "บริการเล็ก ๆ" หลายตัวคุยกันผ่าน API (เช่น service สำหรับ Order, User, Payment แยกกัน) — ต่างจาก monolith ที่รวมทุกอย่างใน process เดียว · เจาะลึกใน System Design / Microservices
แต่ละลูกศร = API call:
- Browser → CDN: HTTP REST (cache)
- Mobile → API Gateway: HTTPS REST/GraphQL
- BFF → Microservices: gRPC — เหมาะกับ service ภายในที่เน้น throughput (รายละเอียดเรื่อง binary format + HTTP/2 ดูในข้อ 8)
- Service → DB: SQL/NoSQL
Insight: API ไม่ได้อยู่แค่ "ระหว่าง frontend กับ backend" — อยู่ทุกที่ในระบบ
4. ประเภทของ API (Architecture Style)
มีหลาย style — แต่ละแบบมีจุดประสงค์ต่างกัน:
คำอ่าน + ตัวย่อก่อนเข้าตาราง (เพื่อไม่ให้มึน):
- REST (เรสต์) = Representational State Transfer
- GraphQL (กราฟ-คิว-แอล) = Graph Query Language
- gRPC (จี-อาร์-พี-ซี) = Google Remote Procedure Call
- RPC (อาร์-พี-ซี) = Remote Procedure Call — เรียก function ข้ามเครื่องเหมือนเรียก function ปกติ
- SSE (เอ็ส-เอ็ส-อี) = Server-Sent Events — server ส่งข้อมูลถึง client ทางเดียวต่อเนื่อง
- SOAP (โซป) = Simple Object Access Protocol — XML-based, ยุคเก่า
- WebSocket (เว็บ-ซ็อก-เก็ต) = connection ค้างไว้คุยสองทาง
- tRPC (ที-อาร์-พี-ซี) = TypeScript RPC
- Connect-RPC (คอน-เน็คต์-อาร์-พี-ซี) = modern RPC จาก Buf
| Style | ปี | จุดเด่น | ใช้กับ |
|---|---|---|---|
| REST ⭐ | 2000 | Simple + ใช้ HTTP | Web API ทั่วไป — ส่วนใหญ่ของ public API ยุคนี้ |
| GraphQL | 2015 | Client query แค่ที่ใช้, 1 endpoint | Mobile + multi data source |
| gRPC | 2016 | Binary + fast + typed | Microservice ↔ microservice |
| WebSocket | 2011 | Bidirectional persistent | Real-time (chat, game) |
| SSE | 2009 | Server → client stream | Notification, AI chat (OpenAI ChatGPT!) |
| SOAP | 2000 | XML + strict (SOAP 1.0 1998, 1.2 W3C Rec 2007) | Legacy enterprise (avoid) |
| tRPC | 2021 | End-to-end TypeScript | TypeScript-only stack |
| Connect-RPC | 2022 | Modern gRPC + HTTP/JSON | Multi-protocol (Buf) |
5. REST — Representational State Transfer
REST = architecture style (ไม่ใช่ protocol)
6 Constraints (ข้อบังคับ 6 ข้อ) ของ REST (Roy Fielding = คนคิด REST ในวิทยานิพนธ์ปี 2000)
| # | Constraint | คำอ่าน | คำแปล | ตัวอย่าง/implication | มือใหม่ต้องเข้าใจ? |
|---|---|---|---|---|---|
| 1 | Client-Server | ไคล-เอนต์-เซิร์ฟ-เวอร์ | แยกหน้าที่ฝั่ง client กับ server | deploy/scale แต่ละฝั่งอิสระ | ✅ ต้องเข้าใจ |
| 2 | Stateless | สเตท-เลส | server ไม่เก็บ session, request ทุกครั้งมี info ครบ | load balance ง่าย, scale horizontal ได้ | ✅ ต้องเข้าใจ |
| 3 | Cacheable | แค็ช-เอเบิล | response บอกว่า cache ได้ไหม | ลด latency + ลด load ที่ origin (browser/CDN/proxy) | ✅ ต้องเข้าใจ |
| 4 | Uniform Interface | ยู-นิ-ฟอร์ม-อิน-เทอร์-เฟซ | มาตรฐานเดียว: URI + HTTP method + Hypermedia (ลิงก์ในข้อมูลบอก action ต่อ) | client/server พัฒนาแยกได้ถ้ายึด contract เดิม | ✅ ต้องเข้าใจ (Hypermedia ข้ามได้ก่อน) |
| 5 | Layered System | เล-เยอร์ด-ซิส-เท็ม | มี proxy, gateway, CDN กลางทางได้ | ใส่ API gateway, WAF, CDN ได้โดย client ไม่รู้ | 🟡 ข้ามได้ก่อน (infra) |
| 6 | Code on Demand (optional) | โค้ด-ออน-ดี-มานด์ | server ส่ง JS ให้ client ได้ | ขยาย client runtime — ในทางปฏิบัติแทบไม่ใช้ | 🟡 ข้ามได้ |
เจาะลึก trade-off ของแต่ละ constraint ใน บทที่ 1 — REST Design
ความจริงปี 2026 — RESTful ไม่ใช่ REST แท้
- เกือบไม่มีใครทำ REST ตามนิยามเต็ม (โดยเฉพาะ HATEOAS = ใส่ลิงก์บอก action ต่อในข้อมูล — รายละเอียดบทที่ 1)
- เราใช้ "RESTful" = REST แบบยืดหยุ่นเอาที่ใช้งานได้จริง (pragmatic = เน้นปฏิบัติได้ ไม่ยึดทฤษฎีเป๊ะ)
- Public API ใหญ่ ๆ (Stripe, GitHub, Twitter) = RESTful ไม่ใช่ REST แท้ ๆ6. RESTful — สิ่งที่ใช้จริง
REST มีหลักการเยอะแต่ในทางปฏิบัติปี 2026 มีชุด "สิ่งที่ทำจริง" ที่ตกผลึกแล้ว — resource เป็น noun ใน URL, ใช้ HTTP method/status code ให้ตรงความหมาย, JSON, stateless ส่วนหนึ่งที่เคยถูกสอนแต่ตอนนี้ไม่ทำแล้ว (HATEOAS, XML, SOAP) ก็ควรรู้ไว้ว่าทำไม:
Core Practices
✅ Resource ใน URL (noun, not verb)
✅ HTTP method บอก action (GET/POST/PUT/PATCH/DELETE)
✅ Status code บอก result (200/201/204/400/401/404/500)
✅ JSON body (เกือบหมด)
✅ Stateless (no server session)
✅ Cacheable (ใช้ HTTP cache header)
✅ Pagination (offset, cursor)
✅ Versioning (/v1, /v2)
✅ Error format (RFC 9457 — Problem Details for HTTP APIs; supersede RFC 7807 ปี 2023)สิ่งที่ ไม่ทำ ในปี 2026
- HATEOAS (links in response) — เกินจำเป็น (overkill) ในงานส่วนใหญ่ — OpenAPI ทำได้ดีกว่า
- XML — ปี 2026 เกือบไม่มีใครใช้
- SOAP — legacy เท่านั้น7. GraphQL — Query Language สำหรับ API
ปัญหาที่ REST มี
ตัวอย่าง — แสดงหน้า user profile:
REST:
GET /users/1 → user
GET /users/1/orders → orders
GET /users/1/posts → posts
GET /users/1/notifications → notifications
→ 4 calls = 4 round-trip + over-fetchingSolution — GraphQL
graphql
# 1 query — client ขอเฉพาะ field ที่ต้องการ
query {
user(id: 1) {
name
orders { total }
posts(limit: 5) { title }
notifications(unread: true) { message }
}
}→ 1 call = ครบ + ลด data transfer
ข้อดี / ข้อเสีย
✅ ข้อดี:
- 1 endpoint
- Client ขอเฉพาะที่ใช้ (no over-fetching)
- Strong typed schema
- Self-documenting (introspection — ดู gloss ด้านล่าง)
- Real-time ผ่าน subscription
❌ ข้อเสีย:
- Complexity ↑ (server-side)
- Caching ลำบาก (POST + 1 endpoint)
- N+1 risk ใน resolver (ดู gloss ด้านล่าง)
- File upload ไม่ standardIntrospection (GraphQL) = ความสามารถให้ client "สอบถาม schema ของ API ได้เอง" ว่ามี field/type อะไรบ้าง — ทำให้ tool อย่าง GraphiQL/Apollo Studio generate doc + autocomplete ได้อัตโนมัติ
Resolver = ฟังก์ชันฝั่ง server ที่ทำหน้าที่ "ดึงค่า" ของ 1 field ใน GraphQL query (เช่น resolver
user.ordersดึงรายการ order ของ user คนนั้น)N+1 problem (เอ็น-บวก-วัน-โพรบ-เล็ม):
- คืออะไร — query 1 ครั้งกลายเป็น 1 query หลัก + N query เล็ก ๆ
- เกิดเมื่อไหร่ — resolver ของแต่ละ row ไปเรียก DB ทีละครั้ง เช่น load 100 user แล้ว resolver
user.ordersยิง DB อีก 100 ครั้ง- แก้ยังไง — ใช้ DataLoader / batching รวม query เป็นชุดเดียว · ดู GraphQL & gRPC บทที่ 6
ใช้เมื่อ
- Mobile + web ใช้ data ต่างกัน
- Aggregation จากหลาย microservice (BFF pattern)
- Frontend team ใหญ่ + ต้องการ flexibility
- Public API ที่ client unknown (GitHub v4 API)ดู บทที่ 6 สำหรับลึก
8. gRPC — Binary RPC
หลักการ
อ่าน .proto ยังไง —
.proto(โพร-โท) คือไฟล์ที่นิยาม service + message ของ gRPC เขียนด้วย syntax ชื่อ proto3 เลข= 1,= 2หลังชื่อ field คือ field number (เลข slot ที่ binary format ใช้บอกว่า field ไหนเป็น field ไหน — ไม่ใช่ค่า default) เปลี่ยนเลขนี้ภายหลัง = breaking change · รายละเอียดในบทที่ 6นอกจากนั้น
int64,stringคือ type ของ field และservice/rpcคือคีย์เวิร์ดประกาศ service กับ method
protobuf
// users.proto
syntax = "proto3";
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc ListUsers (ListUsersRequest) returns (stream User); // streaming
}
message User {
int64 id = 1; // field number = 1 (slot ใน binary, ไม่ใช่ค่า default)
string email = 2; // field number = 2
string name = 3; // field number = 3
}→ protoc generate code ให้ทุกภาษา → call เหมือน function ปกติ
ข้อดี / ข้อเสีย
⚠️ ต้องการ source — ตรวจครั้งสุดท้าย 2026-06: ตัวเลขเปรียบเทียบ throughput/latency ของ gRPC vs REST/JSON ผันผวนมากตาม payload size, network, RPS — ก่อนอ้างตัวเลขในงานจริงให้รัน benchmark กับ workload ของตัวเอง
✅ ข้อดี:
- เร็ว (binary + HTTP/2 → payload เล็กกว่า, parse ถูกกว่า JSON มาก โดยเฉพาะ message ขนาดใหญ่/RPC ถี่ — ตัวเลขจริงขึ้นกับ payload + network, ดู gRPC official benchmark)
- Typed (compile-time check)
- Streaming (4 types — unary, server, client, bidi)
- Cross-language (Java, Go, Python, Rust, ...)
- Used by Google, Netflix, Square
❌ ข้อเสีย:
- Browser ไม่ native (ต้อง gRPC-Web หรือ Connect-RPC)
- Less human-readable (debug ยากกว่า JSON)
- Steeper learning curve
- Not great for public APIใช้เมื่อ
- Service ↔ service (internal microservices)
- High-throughput requirement
- Binary data (file, video)
- Multi-language teamsBrowser Support — gRPC-Web / Connect-RPC
Browser → gRPC native = ไม่ได้ (HTTP/2 control ไม่ expose)
ทางออก:
1. gRPC-Web + Envoy proxy
2. Connect-RPC (Buf, ปี 2022+) — modern alternative
- รองรับ HTTP/1.1, HTTP/2, gRPC, gRPC-Web
- Same protobuf
- แต่ usable from browser ตรง ๆ9. WebSocket — Real-time Bidirectional
REST เป็น request-response ทีละทาง แต่บางงานต้องการสื่อสารสองทางแบบ real-time (chat, live data, collaborative editing) — WebSocket เปิด connection ค้างไว้แบบ full-duplex ให้ส่งข้อมูลได้ทั้งสองฝั่งตลอดเวลา เหมาะกับงานที่ทั้ง server และ client ต้อง push หากัน:
HTTP = request-response, single direction at a time
WebSocket = full-duplex, persistent connectionใช้กับ:
- Chat (real-time message)
- Live data (stock price, game state)
- Collaborative editing (Figma, Google Docs)
- Multiplayer game
ดู System Design บทที่ 3 สำหรับลึก
10. Server-Sent Events (SSE) — Underrated Gem
SSE = one-way streaming from server to client over HTTPทำไม SSE กลับมา popular ในปี 2024-2026
OpenAI ChatGPT → SSE! (streaming response)
Anthropic Claude → SSE!
Google Gemini → SSE!
→ AI chat = killer use case ของ SSE
เพราะ AI generate text ทีละ token — ต้อง streamข้อดี / ข้อเสีย vs WebSocket
✅ SSE ดี:
- Simple — HTTP ปกติ + Accept: text/event-stream
- Auto-reconnect built-in
- Firewall-friendly
- Easier to scale (HTTP/2 multiplex)
❌ SSE limit:
- One-way (server → client only)
- ผ่าน proxy / load balancer ที่ buffer = ปัญหา
✅ WebSocket ดี:
- Bidirectional
- Lower latency
- Binary support
❌ WebSocket limit:
- Stateful connection (scaling complex)
- ผ่าน corporate firewall ลำบาก11. tRPC — End-to-End TypeScript (ปี 2021+)
💡 ข้ามได้ถ้าไม่ใช่ TypeScript stack — tRPC ใช้เฉพาะระบบที่ทั้ง frontend + backend เป็น TS เท่านั้น ถ้าคุณใช้ Java/Spring, Python/Django, Go ฯลฯ ข้ามไปข้อ 12 ได้เลย
tRPC ทำให้ frontend เรียก backend ได้เหมือนเรียกฟังก์ชันปกติ พร้อม type-safe ตลอดทาง — เปลี่ยน type ที่ server แล้ว frontend error ทันที โดยไม่ต้องมี schema กลาง (OpenAPI/GraphQL) แต่ใช้ได้เฉพาะ TypeScript ทั้งระบบ เหมาะกับ monorepo internal ไม่เหมาะ public API:
ศัพท์ในตัวอย่าง
publicProcedure= procedure (ฟังก์ชัน) ที่เปิดให้ใครเรียกก็ได้ (ไม่ต้อง auth)z.object({...})= zod (ซอด) คือ library validate input สำหรับ TypeScript —z.number()= "ต้องเป็นเลข".input(...).query(...)= บอกว่ารับ input อะไร แล้วเป็น query (อ่านข้อมูล, ไม่ mutate)
typescript
// Server (TypeScript)
const appRouter = router({
getUser: publicProcedure
.input(z.object({ id: z.number() }))
.query(({ input }) => userService.findById(input.id)),
});
// Client (TypeScript)
const user = await trpc.getUser.query({ id: 1 });
// ^? Type: User — fully typed!ข้อดี
✅ Same language (TS) ทั้ง backend + frontend
✅ Type-safe — เปลี่ยน server type → frontend error ทันที
✅ ไม่ต้อง schema (OpenAPI, GraphQL) แยก
✅ Fast developmentข้อเสีย
❌ TypeScript-only — JS/TS ทั้งระบบ
❌ ไม่ดี cross-language
❌ ไม่เหมาะ public APIใช้เมื่อ
- Next.js + TypeScript fullstack
- Internal monorepo (Turborepo + TS)
- Speed of development สำคัญ12. เปรียบเทียบ Style
เรียน API style มาหลายแบบ ตารางนี้สรุปเทียบทุกมิติในที่เดียว แยกเป็น 2 ตารางย่อย — (A) transport/format/schema (B) ความเหมาะกับ context การใช้งาน ใช้เป็นภาพรวมก่อนตัดสินใจเลือกในหัวข้อถัดไป:
อ่านตาราง — Legend
- ✅ = ใช้งานได้ดี · ⭐ = แนะนำ/best fit · ⭐⭐ = ดีที่สุดเมื่อเทียบกัน
- 🔶 = ใช้ได้แต่ติดข้อจำกัด (ดู footnote ใต้ตาราง) · ❌ = ไม่เหมาะ/ไม่รองรับ
- หมายเหตุ: ใช้ 🔶 (ไม่ใช่ ⚠️) เพื่อไม่ชนกับสัญลักษณ์ warning ปกติของเล่ม
ทำไม REST cache ได้แต่ GraphQL/gRPC ยาก? — HTTP cache (browser, CDN, shared proxy) ใช้
GET + URLเป็น cache key + อ่าน headerCache-Control/ETag/Varyเพื่อตัดสินใจ ส่วน GraphQL ส่งPOST+ query ใน body, gRPC ส่ง binary frame — shared cache อ่าน key/payload ไม่ได้ ต้อง cache ที่ application layer (Apollo persisted queries, Redis) แทน
(A) Transport / Format / Schema
| มิติ | REST | GraphQL | gRPC | tRPC | WebSocket |
|---|---|---|---|---|---|
| Transport | HTTP/1.1+ | HTTP | HTTP/2 | HTTP | TCP upgrade |
| Format | JSON | JSON | Protobuf | JSON | JSON/binary |
| Schema | OpenAPI (opt) | GraphQL schema | .proto (req) | TS types | (none) |
| Endpoint | Many | One | Many (RPC) | Many | One persistent |
| Caching | HTTP cache | Hard | Hard | Hard | streaming — ไม่มี HTTP cache semantics |
| Discovery | Manual | Introspection | Native | Native | Manual |
| Learning curve | Low | Medium | High | Low (TS) | Medium |
(B) ความเหมาะกับ Context
| Context | REST | GraphQL | gRPC | tRPC | WebSocket |
|---|---|---|---|---|---|
| Browser | ✅ | ✅ | 🔶 (gRPC-Web) | ✅ | ✅ |
| Mobile | ✅ | ✅⭐ | ✅ | 🔶 TS only | ✅ |
| Microservice | ✅ | 🔶 | ⭐ | ❌ ¹ | 🔶 |
| File upload | ✅ | 🔶 | ✅ | 🔶 | 🔶 |
| Streaming | SSE/WS | Subscription | ⭐ Native | ✅ (sub) | ⭐ Native |
| Public API | ⭐⭐ | ⭐ (GitHub v4) | 🔶 | ❌ ¹ | 🔶 |
¹ Footnote — ทำไม tRPC = ❌ สำหรับ Microservice + Public API: tRPC แชร์ TypeScript type ระหว่าง client/server ผ่าน type import โดยตรง — service ภาษาอื่น (Go, Java, Python) เรียกไม่ได้ เลยไม่เหมาะกับ polyglot microservices หรือ public API ที่ client ไม่รู้ว่าใช้ภาษาอะไร
13. กฎทอง — เลือก Style
สรุปเป็นกฎตัดสินใจเร็ว ๆ — ไม่ต้องจำตารางทั้งหมด แค่ถามว่างานคืออะไร: public API ทั่วไปใช้ REST (default), flexible query ใช้ GraphQL, service-to-service ใช้ gRPC, real-time ใช้ WebSocket/SSE flowchart นี้พาไปยังตัวเลือกที่เหมาะ:
หนังสือนี้ → focus REST (style ที่ใช้กว้างที่สุด) + GraphQL/gRPC intro (บทที่ 6)
หมายเหตุเรื่องโค้ด: ตัวอย่างโค้ดในเล่มนี้ส่วนใหญ่เป็น Java/Spring Boot (กับ TypeScript/React บ้าง) ถ้าคุณไม่คุ้นภาษาเหล่านี้ ไม่ต้องกังวล — อ่านเอาแค่ "แนวคิด" ของแต่ละหัวข้อก็พอ หลักการออกแบบ API ใช้ได้กับทุกภาษา
14. HTTP Foundation — สิ่งที่ต้องเข้าใจก่อน
API ส่วนใหญ่ปี 2026 = HTTP-based → ต้องเข้าใจ HTTP ก่อน
HTTP Versions
จุดเด่นที่ต้องรู้ใน 2 บรรทัด: HTTP/2 ส่งหลาย request พร้อมกันใน connection เดียวได้ (multiplexing) · HTTP/3 เปลี่ยน TCP → UDP (ผ่าน QUIC) เพื่อ handshake สั้นกว่าและไม่มีปัญหา head-of-line blocking ระดับ TCP
| Version | ปี | Status ปี 2026 |
|---|---|---|
| HTTP/1.0 | 1996 | Legacy |
| HTTP/1.1 | 1997 | ยังใช้กันมาก |
| HTTP/2 | 2015 | Mainstream (multiplexing, header compression) |
| HTTP/3 | 2022 | Growing (ใช้ QUIC transport — ดูรายละเอียดด้านล่าง) |
HTTP/2 Features ที่ปี 2026 standard
✅ Multiplexing (มัล-ติ-เพล็ก-ซิง) — หลาย request พร้อมกันใน connection เดียว
✅ Header compression (HPACK = เอช-แพ็ก = อัลกอริทึมบีบ header)
✅ Server push — ถูก deprecate: Chrome ถอด support ปี 2022 และ Firefox ตามมา
ใช้ 103 Early Hints แทนสำหรับ resource preload (กรณี bidirectional push อื่น ๆ ไม่มีตัวแทนตรง ๆ)
✅ Binary protocol
✅ ต้องใช้ TLS เกือบทุก browserHTTP/3 (QUIC) — Modern
QUIC อ่านว่า "ควิก" (Quick UDP Internet Connections)
จุดเด่นของ HTTP/3 + QUIC แยกเป็น feature ละบรรทัด:
- Transport: UDP (ยู-ดี-พี) — ไม่ใช่ TCP แล้ว
- 0-RTT handshake (ซี-โร-อาร์-ที-ที) — เริ่มคุยกันได้เร็วกว่า TCP+TLS (มี handshake น้อยรอบกว่า)
- แก้ head-of-line blocking (เฮด-ออฟ-ไลน์-บล็อก-กิ้ง) — ใน TCP ถ้า packet หนึ่งติด ตัวที่เหลือต้องรอ; QUIC แต่ละ stream แยกกัน
- Connection migration — สลับ network (WiFi ↔ 4G) แล้ว connection ไม่หลุด เพราะใช้ connection ID ไม่ใช่ IP:port
- Encrypted by default — TLS 1.3 built-in
Adoption ปี 2026: Cloudflare, Google, Meta ใช้แล้ว — others กำลังตาม
15. คำศัพท์พื้นฐาน
| คำ | คำอ่าน | ความหมาย |
|---|---|---|
| Endpoint | เอ็นด์-พอยต์ | URL ของ API เช่น /api/users/1 |
| Resource | รี-ซอร์ส | สิ่งที่ API เปิดให้เข้าถึง (user, order, product) |
| HTTP Method | เอช-ที-ที-พี-เม็ธ-อ็อด | GET/POST/PUT/PATCH/DELETE |
| Status Code | สเต-ตัส-โค้ด | 200/201/400/404/500 ฯลฯ |
| Header | เฮด-เดอร์ | metadata ของ request/response (Auth, Content-Type) |
| Body | บอ-ดี้ | data ที่ส่ง (JSON ส่วนใหญ่) |
| Payload | เพย์-โหลด | = body |
| Query Parameter | คเว-รี-พา-รา-มิ-เตอร์ | ?key=value ใน URL |
| Path Parameter | พาธ-พา-รา-มิ-เตอร์ | /users/{id} |
| Idempotent | ไอ-เด็ม-โพ-เทนต์ | เรียกซ้ำได้ผลเดิม (GET, PUT, DELETE) |
| Safe | เซฟ | ไม่เปลี่ยน state (GET, HEAD) |
| Stateless | สเตท-เลส | server ไม่จำ context — ทุก request มี info ครบ |
| CORS | คอร์ส | Cross-Origin Resource Sharing — browser policy |
| Content negotiation | คอน-เทนต์-นี-โก-ชิ-เอ-ชั่น | client + server ตกลง format (JSON/XML/etc.) |
| MIME type | ไมม์-ไทป์ | media type เช่น application/json, text/event-stream |
| Authentication | ออ-เธน-ทิ-เค-ชั่น | "คุณคือใคร?" (token, key) |
| Authorization | ออ-ธอ-ไร-เซ-ชั่น | "คุณทำอะไรได้?" (role, permission) |
| Rate limit | เรต-ลิ-มิต | จำกัด request ต่อเวลา |
| OpenAPI | โอ-เพ่น-เอ-พี-ไอ | spec มาตรฐานสำหรับ describe REST API |
16. HTTP Methods ที่ใช้บ่อย
Safe vs Idempotent — ต่างกันยังไง (สำคัญมาก อย่าสับสน):
- Safe (เซฟ) = "อ่านอย่างเดียว ไม่เปลี่ยน state ของ server" — เรียกกี่ครั้งก็เหมือนไม่ได้เรียก เช่น
GET- Idempotent (ไอ-เด็ม-โพ-เทนต์) = "เรียกซ้ำ N ครั้ง ได้ผลลัพธ์เหมือนเรียก 1 ครั้ง" — อาจเปลี่ยน state ครั้งแรก แต่ครั้งที่ 2-N ไม่เพิ่ม side effect
- Safe ทุกตัวเป็น Idempotent โดยอัตโนมัติ (เพราะไม่เปลี่ยนอะไรเลย) แต่ Idempotent ไม่จำเป็นต้อง Safe
- Analogy ไทย ๆ: idempotent = เหมือนกดปุ่ม "ปิด" พัดลม กดกี่ครั้งก็ปิดเหมือนเดิม
| Method | คำอ่าน | ใช้ทำอะไร | มี Body? | Safe? | Idempotent? |
|---|---|---|---|---|---|
GET | เก็ต | อ่าน | ❌ | ✅ | ✅ |
HEAD | เฮด | เหมือน GET — ไม่มี body | ❌ | ✅ | ✅ |
OPTIONS | อ็อพ-ชั่น | CORS preflight + capabilities | ❌ | ✅ | ✅ |
POST | โพสต์ | สร้าง / action | ✅ | ❌ | ❌ (ใช้ Idempotency-Key header เพื่อ retry-safe) |
PUT | พุท | แทนที่ทั้ง resource | ✅ | ❌ | ✅ |
DELETE | ดี-ลีท | ลบ | ❌/✅ | ❌ | ✅ |
PATCH | แพตช์ | แก้บางส่วน | ✅ | ❌ | ❌ (ไม่จำเป็นต้อง idempotent) ¹ |
¹ ทำไม PATCH ไม่ idempotent (RFC 5789) — PATCH ขึ้นกับ patch format:
- JSON Merge Patch (RFC 7396) — โดยทั่วไป idempotent (apply patch เดิมซ้ำ ๆ ได้ผลเหมือนเดิม)
- JSON Patch (RFC 6902) กับ
op: addบน array — NOT idempotent (apply 2 ครั้งจะ append 2 ครั้ง)- ดังนั้นในทางมาตรฐาน RFC 5789 บอกชัดว่า PATCH ไม่จำเป็นต้อง idempotent
Idempotent คืออะไร — เรียกซ้ำ N ครั้ง = ผลเดียวกับ 1 ครั้ง
DELETE /users/1 ← เรียก 100 ครั้ง = user 1 ถูกลบ (เหมือนเดิม)
POST /users {...} ← เรียก 100 ครั้ง = สร้าง 100 user (ต่างกัน — ไม่ idempotent)
PUT /users/1 {...} ← เรียก 100 ครั้ง = state เหมือนเดิม (idempotent จากมุม client)หมายเหตุ: idempotent วัดจาก "effect ที่ client สังเกตเห็น" — ถ้า server เขียน
updated_at = NOW()ลง DB ทุก PUT ค่า timestamp อาจต่างกัน แต่ resource state (ที่ client สนใจ) เหมือนเดิม ก็ยังนับเป็น idempotent
→ Retry safe เฉพาะ idempotent operations
→ สำหรับ POST — ใช้ Idempotency-Key (ไอ-เด็ม-โพ-เทน-ซี่-คีย์) header pattern แบบ Stripe: client ส่ง UUID ติดไปกับ request, server จำคู่ key→response ไว้ระยะหนึ่ง ถ้า retry ด้วย key เดิม → ส่ง response เดิมกลับ ไม่สร้าง resource ซ้ำ
HATEOAS (อ่านว่า "ฮา-ทิ-โอ-เอส") = Hypermedia As The Engine Of Application State — หลักการใส่ลิงก์ action ต่อ ๆ ไปในตัว response เพื่อให้ client เดินตาม state machine ของ API ได้โดยไม่ต้อง hardcode URL · ใช้น้อยในทางปฏิบัติ — รายละเอียดในบทที่ 1
17. HTTP Status Code ที่ใช้บ่อย
จำเป็นต้องจำ 16 ตัวนี้ก่อน (ที่เหลือดู MDN: HTTP status เมื่อต้องใช้):
| Class | Code | ชื่อ | ความหมายไทย | ตัวอย่าง use case |
|---|---|---|---|---|
| 2xx Success | 200 | OK | สำเร็จ + มี body | GET /users/1 → return user |
201 | Created | สร้างสำเร็จ | POST /users → response มี Location: /users/123 header + body = resource ใหม่ | |
204 | No Content | สำเร็จ + ไม่มี body | DELETE /users/1 สำเร็จ | |
| 3xx Redirect | 301 | Moved Permanently | URL เปลี่ยนถาวร | API endpoint ย้ายถาวร, browser/SEO ควร update |
302 | Found | redirect ชั่วคราว | login flow redirect | |
304 | Not Modified | cache ยังใช้ได้ | client ส่ง If-None-Match, server ตอบ 304 ให้ใช้ cache | |
| 4xx Client Error | 400 | Bad Request | request format ผิด | JSON parse error, missing required field |
401 | Unauthorized | ยังไม่ login / token หมดอายุ | ไม่มี Authorization header | |
403 | Forbidden | login แล้วแต่ไม่มีสิทธิ์ | user ปกติพยายามเข้า admin endpoint | |
404 | Not Found | resource ไม่มี | GET /users/9999 ที่ไม่มีจริง | |
409 | Conflict | ขัดแย้งกับ state ปัจจุบัน | email ซ้ำตอน signup, ETag ไม่ตรง (concurrent update) | |
422 | Unprocessable Entity | syntax ถูกแต่ semantic ผิด | JSON ถูก format แต่ age = -5 (validation fail) | |
429 | Too Many Requests | rate limit | client ยิงเกินโควต้า | |
| 5xx Server Error | 500 | Internal Server Error | server พัง (unhandled exception) | NullPointerException ใน controller |
502 | Bad Gateway | proxy/upstream error | nginx ติดต่อ backend ไม่ได้ | |
503 | Service Unavailable | server overload/maintenance | scheduled downtime, circuit breaker open | |
504 | Gateway Timeout | proxy timeout | nginx รอ backend นานเกินกำหนด |
409 vs 422 — แยกอย่างไร (RFC 9110):
- 400 = ผิด syntax (parse ไม่ผ่าน เช่น JSON broken)
- 422 = syntax ถูก แต่ semantic ผิด (เช่น
age: -5, password สั้นเกินไป) — เรียกว่า validation fail- 409 = request ถูก แต่ขัดกับ state ปัจจุบันของ resource (email ซ้ำ, version mismatch จาก ETag)
201 vs 200 ตอน create: REST บอกชัดว่าควรใช้
201 Created+Locationheader เมื่อสร้าง resource ใหม่ ไม่ใช่ 200 (200 ใช้กับ "อ่านสำเร็จ" หรือ action ที่ไม่สร้าง resource)
Status code ที่ไม่ได้อยู่ในตารางหลัก (ไว้อ้างอิงเมื่อต้องใช้)
1xx Informational(rare):100 Continue,101 Switching Protocols(WebSocket upgrade),103 Early Hints(preload, HTTP/2+)307 Temporary Redirect/308 Permanent Redirect— เหมือน 302/301 แต่ บังคับให้ method เดิม (ไม่เปลี่ยน POST → GET)405 Method Not Allowed— endpoint มี แต่ไม่รองรับ method นี้410 Gone— resource หายถาวร (เคยมี, ลบแล้ว)412 Precondition Failed—If-Match/If-Unmodified-Sinceไม่ตรง (optimistic locking) · ใช้คู่กับ ETag425 Too Early— เฉพาะกรณี TLS 1.3 0-RTT replay protection เท่านั้น ไม่ใช่ "client retry เร็วเกิน" ทั่วไป- ดู MDN: HTTP status สำหรับครบทุก code
กฎทอง: HTTP status code = contract. ห้าม return 200 +
{"error": ...}
18. API Design Principles (ใช้ตลอดเล่ม)
10 หลักการที่จะกล่าวซ้ำในทุกบท:
- Consistency — endpoint, naming, response format เหมือนกัน
- Resource-oriented — endpoint = noun + plural (
/users,/orders) - HTTP semantics — ใช้ method + status code ตามมาตรฐาน
- Stateless — ไม่ใช้ session
- Versioning — รองรับ breaking change
- Documentation — OpenAPI / Swagger (auto-generated)
- Security — auth + HTTPS + rate limit
- Error format — consistent + helpful (RFC 7807/9457)
- Pagination — list ใหญ่ ต้อง paginate (cursor preferred)
- Idempotency — ที่ทำได้ ให้ idempotent
19. ตัวอย่าง API ที่ออกแบบดี
# Books API
GET /api/v1/books # list
GET /api/v1/books?author=orwell&page=2&size=20 # filter + pagination
GET /api/v1/books/{id} # detail
POST /api/v1/books # create
PUT /api/v1/books/{id} # full update
PATCH /api/v1/books/{id} # partial update
DELETE /api/v1/books/{id} # delete
# Nested
GET /api/v1/books/{id}/reviews # reviews ของหนังสือ
POST /api/v1/books/{id}/reviews # add review
# Action (non-CRUD) — ใช้ verb ได้ในกรณีพิเศษ
POST /api/v1/books/{id}/archive
POST /api/v1/orders/{id}/cancel
POST /api/v1/users/{id}/reset-passwordสังเกต:
- noun + plural (
/booksไม่ใช่/getBook) - HTTP method ตรงกับ action
- URL hierarchy สื่อความสัมพันธ์
- Versioning ใน URL (
/v1)
20. ลองเขียน API กันเอง
ก่อนเข้าบทถัดไป — ลองออกแบบ API ของระบบที่คุณรู้จัก:
- ห้องสมุด (book, member, loan)
- E-commerce (product, cart, order)
- Social media (post, comment, like)
- TODO app (task, project)
เขียน 10-15 endpoint — ไม่ต้องสมบูรณ์ — อ่านบทถัดไปแล้วกลับมาแก้
21. Real-World API ตัวอย่างที่ดี (ให้ดูเป็น reference)
✅ Stripe API (stripe.com/docs/api)
- Consistent REST
- Excellent error format
- Idempotency-Key
- Versioning by date
- Best documentation in industry
✅ GitHub REST API v3 (docs.github.com/rest)
- Good REST patterns
- Pagination via Link header
- Rate limit headers
✅ GitHub GraphQL API v4
- Best GraphQL public API
- Relay cursor pagination
✅ Twilio API
- Webhook security
- Good error handling
⚠️ Twitter/X API
- Mixed quality (v1 vs v2)
- Good auth (OAuth2)
- Rate limit ระบุชัดฝึก: เปิด Stripe API docs — ดู
POST /v1/chargesลึก ๆ → จดเทคนิคที่ใช้
22. Checkpoint — ฝึกทำเอง
🛠️ Checkpoint 0.1 — Critique API
เปิด API doc ของบริการที่คุณใช้ (GitHub, Stripe, Twitter) — ดู:
- URL pattern เป็นยังไง?
- Status code ใช้ครบ?
- Error format?
- Versioning?
- Pagination strategy?
🛠️ Checkpoint 0.2 — Design First API
ออกแบบ API สำหรับ "TODO app":
- Resource: user, task, project
- 10 endpoint ครบ CRUD
- ตอบ: GET/POST/PUT/PATCH/DELETE
- ใส่ status code ที่ถูก
🛠️ Checkpoint 0.3 — เลือก Style
สำหรับ scenario ต่อไปนี้ — เลือก REST / GraphQL / gRPC / WebSocket / SSE / tRPC:
- Mobile app + dashboard ที่ใช้ data ต่างกัน
- Service A เรียก Service B 10,000 ครั้ง/วินาที (internal)
- Chat application
- Public API ให้ developer
- Live cricket score broadcast
- AI chatbot ที่ stream response
- Next.js TypeScript fullstack monorepo
- Trading platform (real-time price)
🛠️ Checkpoint 0.4 — HTTP Status Code Drills
จำเป็น — ลอง quiz ตัวเอง:
- User ไม่ login เรียก protected → ?
- User login แต่ไม่มีสิทธิ์ → ?
- Email ซ้ำตอน signup → ?
- รัน 1 ปีแล้ว retire endpoint → ?
- Validation fail → ?
- Server down maintenance → ?
23. สรุปบท
✅ API = สัญญา + interface ระหว่าง 2 ระบบ
✅ API ที่ดี = consistent, RESTful, well-documented, secure
✅ Style: REST (default ส่วนใหญ่), GraphQL (flexible), gRPC (microservices), WebSocket (real-time), SSE (AI chat!), tRPC (TS-only)
✅ Core principles: stateless, cacheable, resource-oriented, HTTP semantics
✅ HTTP method: GET (read), POST (create), PUT/PATCH (update), DELETE (delete)
✅ Status code: 2xx success, 4xx client error, 5xx server error
✅ Idempotent (GET/PUT/DELETE) = retry safe
✅ Design = critical สำหรับ public API (change ยาก) — internal ก็ควรทำดี
✅ HTTP/2 + HTTP/3 = mainstream ปี 2026 — multiplexing, QUIC
✅ Real-world: Stripe = gold standard, GitHub v4 = GraphQL best practice
24. คำศัพท์เพิ่ม
| คำศัพท์ | อ่านยังไง | ความหมาย |
|---|---|---|
| API | เอ-พี-ไอ | Application Programming Interface |
| REST | เรสต์ | Representational State Transfer (architecture style) |
| RESTful | เรสต์-ฟูล | Pragmatic REST (ไม่ purist) |
| GraphQL | กราฟ-คิว-แอล | Query language สำหรับ API |
| gRPC | จี-อาร์-พี-ซี | Google RPC framework |
| tRPC | ที-อาร์-พี-ซี | TypeScript end-to-end typed RPC |
| Connect-RPC | คอน-เน็คต์-อาร์-พี-ซี | Modern gRPC + HTTP/JSON (Buf, 2022+) |
| WebSocket | เว็บ-ซ็อก-เก็ต | Persistent bidirectional connection |
| SSE | เอ็ส-เอ็ส-อี | Server-Sent Events (one-way streaming) |
| HTTP/1.1 | เอช-ที-ที-พี-วัน-จุด-วัน | Standard since 1997 |
| HTTP/2 | เอช-ที-ที-พี-ทู | Multiplexing + binary (2015+) |
| HTTP/3 (QUIC) | เอช-ที-ที-พี-ทรี (ควิก) | UDP-based, faster (2022+) |
| JSON | เจ-ซัน | JavaScript Object Notation (format) |
| MIME type | ไมม์-ไทป์ | Media type (application/json) |
| CORS | คอร์ส | Cross-Origin Resource Sharing |
| Idempotency | ไอ-เด็ม-โพ-เทน-ซี | ทำซ้ำได้ผลเดิม |
| HATEOAS | ฮา-ทิ-โอ-เอส | Hypermedia As The Engine Of Application State |
| OpenAPI | โอ-เพ่น-เอ-พี-ไอ | REST API specification (เคยชื่อ Swagger) |
| AsyncAPI | อะ-ซิงค์-เอ-พี-ไอ | Event-driven API specification |
| JSON Schema | เจ-ซัน-สคี-มา | Validate JSON structure |
Glossary: ../glossary.md · Style guide: ../CONTRIBUTING.md last_verified: 2026-06-03 · review report: ../REVIEW-2026-06-03.md