ข้ามไปยังเนื้อหา

กายวิภาคของข้อความ HTTP

การออกแบบ API ให้ดีเริ่มต้นจากการมองเห็นอย่างชัดเจนว่ามีอะไรวิ่งผ่านสายส่งบ้าง การแลกเปลี่ยน HTTP ก็เป็นเพียงข้อความเท่านั้น คือ request จาก client และ response จาก server ซึ่งแต่ละฝั่งมีสามส่วนเหมือนกัน

request มี start line (method + target + เวอร์ชัน HTTP) ชุดของ header และ body ที่จะมีหรือไม่ก็ได้:

POST /articles HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGci...
Accept: application/json
{ "title": "Designing APIs", "body": "..." }

method (POST) บอกว่า จะทำ อะไร target (/articles) บอกว่า ทำกับ อะไร ส่วน header พกพา metadata (content type, auth, สิ่งที่ client ยอมรับได้) และ body พกพา payload

response สะท้อนรูปแบบนั้น คือ status line (เวอร์ชัน + status code + reason) header และ body ที่จะมีหรือไม่ก็ได้:

HTTP/1.1 201 Created
Content-Type: application/json
Location: /articles/42
{ "id": 42, "title": "Designing APIs" }
flowchart LR
  subgraph Request
    A[Start line: method + path] --> B[Headers] --> C[Body optional]
  end
  subgraph Response
    D[Status line: code + reason] --> E[Headers] --> F[Body optional]
  end
  Request -->|over HTTP| Response
Request และ response มีโครงสร้างสามส่วนเหมือนกัน

framework ฝั่ง server ซ่อนรายละเอียดเหล่านี้ไว้เกือบทั้งหมด แต่การได้ลองสร้าง response ด้วยมือสักครั้งก็ช่วยได้มาก โค้ดส่วนนี้สร้าง header และ JSON body สำหรับ response แบบ “created” แล้ว log ออกมา:

JavaScript
ข้อดี (HTTP Structure)ข้อแลกเปลี่ยน
มาตรฐานสากล — ทุก client รู้วิธีอ่าน request/responseverbose กว่า binary protocol เช่น gRPC
text-based — human-readable, ง่าย debug ด้วย curlheader overhead ทุก request — HTTP/2 แก้ด้วย header compression
stateless — ทุก request มีข้อมูลครบในตัวเองต้องส่ง auth header ทุกครั้ง ต่างจาก session-based
cacheable — browser และ CDN cache ได้จาก headercaching config ผิดทำให้ client เห็นข้อมูลเก่า

ใส่ข้อมูลสำคัญใน URL แทน Header อาการ:

  • ส่ง token ใน query string: GET /users?token=abc123
  • token ติด URL ทำให้ log และ browser history เก็บไว้
  • ใช้ Authorization: Bearer <token> ใน header เสมอ

ไม่ Set Content-Type อาการ:

  • ส่ง JSON body โดยไม่ใส่ Content-Type: application/json
  • server parse body ผิด หรือ reject request
  • ตั้ง Content-Type ทุกครั้งที่ request มี body

💡 ตัวอย่างจากของจริง

GitHub API:

  • ทุก request ต้องมี Accept: application/vnd.github+json
  • บอก server ว่า client ต้องการ JSON response version ล่าสุด

Stripe API:

  • ใช้ Idempotency-Key header สำหรับ POST request ที่ sensitive
  • ป้องกัน duplicate charge เมื่อ network retry
ส่วนใดของ HTTP request ที่บอกว่า client ต้องการทำ operation อะไร?
หลังสร้าง resource เสร็จ ตามธรรมเนียมแล้ว response header ตัวไหนจะชี้ไปยัง resource นั้น?
Header Content-Type บน response บอกอะไรแก่ client?