KoderKoder.ai
ราคาองค์กรการศึกษาสำหรับนักลงทุน
เข้าสู่ระบบเริ่มต้นใช้งาน

ผลิตภัณฑ์

ราคาองค์กรสำหรับนักลงทุน

ทรัพยากร

ติดต่อเราสนับสนุนการศึกษาบล็อก

กฎหมาย

นโยบายความเป็นส่วนตัวข้อกำหนดการใช้งานความปลอดภัยนโยบายการใช้งานที่ยอมรับได้แจ้งการละเมิด

โซเชียล

LinkedInTwitter
Koder.ai
ภาษา

© 2026 Koder.ai สงวนลิขสิทธิ์

หน้าแรก›บล็อก›สร้าง OpenAPI จากพฤติกรรมด้วย Claude Code อย่างตรงไปตรงมา
10 ธ.ค. 2568·2 นาที

สร้าง OpenAPI จากพฤติกรรมด้วย Claude Code อย่างตรงไปตรงมา

เรียนรู้วิธีสร้าง OpenAPI จากพฤติกรรมด้วย Claude Code แล้วเปรียบเทียบกับการใช้งาน API ของคุณ พร้อมตัวอย่างการตรวจสอบฝั่งลูกค้าและเซิร์ฟเวอร์แบบง่ายๆ

สร้าง OpenAPI จากพฤติกรรมด้วย Claude Code อย่างตรงไปตรงมา

ทำไมสัญญา OpenAPI ถึงเบี่ยง (และทำไมเรื่องนี้ถึงสำคัญ)

สัญญา OpenAPI คือคำอธิบายร่วมของ API ของคุณ: มี endpoint อะไรบ้าง, ส่งอะไรเข้าไป, ได้อะไรกลับมา, และข้อผิดพลาดเป็นอย่างไร มันคือข้อตกลงระหว่างเซิร์ฟเวอร์กับใครก็ตามที่เรียกมัน (เว็บแอป โมบายแอป หรือบริการอื่น)

ปัญหาคือการเบี่ยง (drift) — API ที่รันเปลี่ยนไป แต่สเปกไม่เปลี่ยน หรือสเปกถูก “ทำให้สวย” ให้ดูดีกว่าความเป็นจริง ขณะที่การใช้งานยังคงคืนฟิลด์แปลกๆ หายสถานะโค้ด หรือลักษณะข้อผิดพลาดไม่สอดคล้อง ไปเรื่อยๆ ผู้คนก็หยุดไว้ใจไฟล์ OpenAPI และมันกลายเป็นเอกสารอีกชิ้นที่ทุกคนไม่อ่าน

การเบี่ยงมักมาจากแรงกดดันปกติ: แก้ด่วนแล้วไม่อัปเดตสเปก, เพิ่มฟิลด์ตัวเลือกแบบ "ชั่วคราว", การแบ่งหน้าพัฒนาไป, หรือทีมอัปเดต "แหล่งความจริง" ต่างกัน (โค้ดแบ็กเอนด์, คอลเลกชัน Postman, และไฟล์ OpenAPI)

การรักษาความซื่อสัตย์หมายความว่าสเปกต้องตรงกับพฤติกรรมจริง หาก API บางครั้งคืน 409 สำหรับความขัดแย้ง นั่นควรอยู่ในสัญญา ถ้าฟิลด์ nullable ก็ระบุไว้ หากต้องยืนยันตัวตน ก็อย่าทิ้งให้คลุมเครือ

เวิร์กโฟลว์ที่ดีกลุ่มหนึ่งจะให้คุณได้:

  • ไฟล์ OpenAPI ที่สะท้อนพฤติกรรมที่ตั้งใจและที่สังเกตได้
  • ชุดการตรวจสอบง่ายๆ เพื่อจับ drift ตั้งแต่ต้น ก่อนที่ไคลเอนต์จะพัง
  • ตัวอย่างการตรวจสอบฝั่งลูกค้าและฝั่งเซิร์ฟเวอร์ที่ชัดเจนให้คัดใส่โค้ดเบสได้

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

เริ่มจากพฤติกรรมที่ต้องการ ไม่ใช่จากโค้ด

ถ้าคุณเริ่มจากการอ่านโค้ดหรือคัดเส้นทางมา สเปก OpenAPI ของคุณจะบรรยายสิ่งที่มีวันนี้ รวมทั้งความพิสดารที่คุณอาจไม่อยากสัญญาไว้ แทนที่จะทำแบบนั้น ให้บรรยายว่า API ควรทำอะไรสำหรับผู้เรียก แล้วใช้สเปกเพื่อยืนยันว่าแอปพลิเคชันตรงตาม

ก่อนเขียน YAML หรือ JSON ให้เก็บข้อเท็จจริงเล็กๆ ต่อ endpoint:

  • มันทำอะไร (method และ path)
  • รับอะไรบ้าง (headers, query, path params, body)
  • คืนอะไรบ้าง (รหัสสถานะความสำเร็จ รูปร่างการตอบกลับ header สำคัญ)
  • อะไรอาจล้มเหลว (ข้อผิดพลาดที่เป็นไปได้ รหัสสถานะ รูปร่าง body ของข้อผิดพลาด)
  • ใครเรียกได้ (auth และบทบาท ถ้าจำเป็น)

จากนั้นเขียนพฤติกรรมเป็นตัวอย่าง ตัวอย่างบังคับให้คุณระบุชัดเจนและช่วยให้ร่างสัญญาที่สอดคล้องง่ายขึ้น

สำหรับ Tasks API เส้นทางปกติอาจเป็น: “สร้างงานด้วย title และได้กลับ id, title, status, และ createdAt.” เพิ่มความล้มเหลวทั่วไป: “ขาด title คืน 400 พร้อม {\"error\":\"title is required\"}” และ “ไม่มี auth คืน 401.” ถ้าคุณรู้กรณีขอบ ให้ใส่: อนุญาตชื่อซ้ำไหม และเกิดอะไรเมื่อ id งานไม่มีอยู่

จับกฎเป็นประโยคสั้นๆ ที่ไม่ขึ้นกับรายละเอียดโค้ด:

  • “title จำเป็นและมีความยาว 1-120 ตัวอักษร.”
  • “ผลลัพธ์รายการคืนสูงสุด 50 รายการ เว้นแต่ตั้ง limit (สูงสุด 200).”
  • “dueDate เป็น ISO 8601 date-time.”
  • “เอนด์พอยต์ที่เขียนต้องใช้โทเค็นผู้ใช้.”

สุดท้าย ตัดสินขอบเขต v1 ถ้าไม่แน่ใจ ให้ทำ v1 เล็กและชัด (create, read, list, update status). เก็บการค้นหา อัปเดตเป็นจำนวนมาก และฟิลเตอร์ซับซ้อนไว้ทีหลังเพื่อให้สัญญาน่าเชื่อถือ

เทมเพลตน้ำหนักเบาสำหรับอธิบาย endpoints

ก่อนขอให้ Claude Code เขียนสเปก ให้เขียนบันทึกพฤติกรรมในรูปแบบสั้นๆ และทำซ้ำได้ เป้าหมายคือทำให้ยากที่จะ "เติมช่องว่าง" ด้วยการเดา

เทมเพลตที่ดีต้องสั้นพอที่จะใช้งานจริง แต่สอดคล้องพอที่สองคนจะอธิบาย endpoint เดียวกันได้แบบใกล้เคียงกัน เก็บโฟกัสที่สิ่งที่ API ทำ ไม่ใช่วิธีที่มันถูกทำ

เทมเพลตบันทึกพฤติกรรมของ endpoint

ใช้บล็อกหนึ่งบล็อกต่อ endpoint:

METHOD + PATH:
Purpose (1 sentence):
Auth:
Request:
- Query:
- Headers:
- Body example (JSON):
Responses:
- 200 OK example (JSON):
- 4xx example (status + JSON):
Edge cases:
Data types (human terms):

เขียนอย่างน้อยหนึ่งคำขอที่เป็นรูปธรรมและสองการตอบกลับ รวมสถานะโค้ดและตัวอย่าง JSON ที่สมจริง ถ้าฟิลด์เป็นตัวเลือก ให้แสดงตัวอย่างที่มันหายไป

ชี้จุด edge cases ชัดเจน นี่คือที่ที่สเปกเงียบๆ มักจะไม่เป็นจริงต่อไปเพราะทุกคนสมมติคนละอย่าง: ผลลัพธ์ว่าง, ID ไม่ถูกต้อง (400 vs 404), ซ้ำ (409 vs พฤติกรรม idempotent), คำขอไม่ผ่านการตรวจสอบ และขอบเขตการแบ่งหน้า

ยังระบุประเภทข้อมูลด้วยคำง่ายๆ ก่อนคิดถึง schema: string vs number, รูปแบบ date-time, boolean, และ enum (รายการค่าที่อนุญาต) นี่ป้องกันสเปกที่ "สวย" แต่ไม่ตรงกับ payload จริง

ร่างสเปก OpenAPI ด้วย Claude Code (prompt แบบที่ใช้ได้)

Claude Code ทำงานได้ดีเมื่อคุณปฏิบัติต่อมันเหมือนคนจดบันทึกที่ระมัดระวัง ให้บันทึกพฤติกรรมและกฎที่เข้มงวดสำหรับวิธีเขียน OpenAPI ถ้าคุณแค่บอกว่า “เขียนสเปก OpenAPI” มันมักจะเดา ชื่อนามไม่สอดคล้อง และขาดกรณีข้อผิดพลาด

วางบันทึกพฤติกรรมไว้ก่อน แล้วเพิ่มบล็อกคำสั่งเข้มงวด ตัวอย่าง prompt ที่ใช้ได้จริง:

You are generating an OpenAPI 3.1 YAML spec.
Source of truth: the behavior notes below. Do not invent endpoints or fields.
If anything is unclear, list it under ASSUMPTIONS and leave TODO markers in the spec.

Requirements:
- Include: info, servers (placeholder), tags, paths, components/schemas, components/securitySchemes.
- For each operation: operationId, tags, summary, description, parameters, requestBody (when needed), responses.
- Model errors consistently with a reusable Error schema and reference it in 4xx/5xx responses.
- Keep naming consistent: PascalCase schema names, lowerCamelCase fields, stable operationId pattern.

Behavior notes:
[PASTE YOUR NOTES HERE]

Output only the OpenAPI YAML, then a short ASSUMPTIONS list.

หลังได้ร่าง ให้สแกนส่วน ASSUMPTIONS ก่อน นั่นคือที่ที่ความซื่อสัตย์จะชนะหรือแพ้ อนุมัติสิ่งที่ถูกต้อง แก้สิ่งที่ผิด แล้วรันใหม่พร้อมบันทึกที่อัปเดต

เพื่อให้ชื่อนิ่ง ให้ระบุข้อตกลงการตั้งชื่อล่วงหน้าและยึดตาม เช่น pattern ของ operationId, ชื่อ tag ที่เป็นคำนามเท่านั้น, ชื่อ schema แบบเอกพจน์, schema Error เดียวที่ใช้ร่วม, และชื่อ auth scheme เดียวที่ใช้ทุกที่

ถ้าคุณทำงานใน workspace แบบ vibe-coding อย่าง Koder.ai จะช่วยเก็บ YAML เป็นไฟล์จริงตั้งแต่ต้นและ iterate ทีละ diff คุณจะเห็นการเปลี่ยนแปลงมาจากการตัดสินใจพฤติกรรมที่อนุมัติแล้วหรือจากสิ่งที่โมเดลเดา

ตรวจสอบสเปกก่อนเทียบกับ API ที่รันจริง

แก้ drift ทีละ endpoint
แก้ drift หนึ่ง endpoint, ทดสอบตอบกลับจริง, และแก้ความแตกต่างตอนยังเล็กอยู่
เปรียบเทียบตอนนี้

ก่อนเทียบกับโปรดักชัน ให้แน่ใจว่าไฟล์ OpenAPI ภายในสอดคล้อง นี่คือที่เร็วที่สุดที่จะจับความคิดหวังและคำพูดคลุมเครือ

อ่านแต่ละ endpoint ราวกับว่าคุณเป็นนักพัฒนาไคลเอนต์ โฟกัสที่สิ่งที่ผู้เรียกต้องส่งและสิ่งที่พวกเขาสามารถพึ่งพาได้รับ

การตรวจทานเชิงปฏิบัติ:\n

  • Required vs optional: ทำเครื่องหมายฟิลด์ที่จำเป็นอย่างถูกต้องและหลีกเลี่ยงการใส่ "ทุกอย่างเป็นตัวเลือก"\n- Types and formats: ระบุ UUID, email, date-time, min/max ให้ชัดเจน\n- Examples: ใส่อย่างน้อยหนึ่งคำขอและหนึ่งการตอบกลับที่สมจริงต่อ endpoint และให้ตัวอย่างสอดคล้องกับ schemas\n- Status codes: ให้สอดคล้องกับบันทึกพฤติกรรมของคุณ (create มักเป็น 201 ไม่ใช่ 200) เลือก 400 vs 422 แล้วใช้ให้สม่ำเสมอ\n- Auth: ระบุว่าจำเป็นต่อ endpoint ใดบ้าง และบทบาทมีผลต่อการเข้าถึงหรือไม่\n ข้อผิดพลาดต้องใส่ใจเป็นพิเศษ เลือกรูปร่างเดียวและใช้ซ้ำทั่ว หากทีมต้องการง่ายมาก ({ error: string }) หรือแบบวัตถุ ({ error: { code, message, details } }) ทั้งสองทำงานได้ แต่อย่าผสมกันใน endpoint ต่างๆ เพราะโค้ดไคลเอนต์จะมีกรณีพิเศษเต็มไปหมด\n สถานการณ์เชิงตรรกะสั้นๆ ช่วยได้ ถ้า POST /tasks ต้อง title สคีมาควรทำเครื่องหมายว่าจำเป็น การตอบกลับความล้มเหลวควรแสดง body ข้อผิดพลาดที่คุณคืนจริง และ operation ควรกำหนดชัดเจนว่าต้องมี auth ไหม

เปรียบเทียบสเปกกับการใช้งาน API ที่รันจริง

เมื่อสเปกอ่านเหมือนพฤติกรรมที่ตั้งใจ ให้ถือว่า API ที่รันเป็นความจริงของสิ่งที่ไคลเอนต์เจอวันนี้ เป้าหมายไม่ใช่ "ชนะ" ระหว่างสเปกกับโค้ด แต่เพื่อค้นหาความต่างตั้งแต่ต้นและตัดสินใจชัดเจนในแต่ละจุด

สำหรับการผ่านแรก ตัวอย่างคำขอ/การตอบกลับจริงมักง่ายที่สุด บันทึกและเทสต์อัตโนมัติถ้ามั่นใจได้ก็ใช้ได้เช่นกัน

มองหาความไม่ตรงกันทั่วไป: endpoint ที่อยู่ในที่หนึ่งแต่ไม่อยู่ในอีกที่, ชื่อฟิลด์หรือรูปร่างต่างกัน, รหัสสถานะต่างกัน (200 vs 201, 400 vs 422), พฤติกรรมที่ไม่มีในเอกสาร (pagination, sorting, filtering), และความต่างเรื่อง auth (สเปกบอกสาธารณะแต่โค้ดต้องใช้โทเค็น)

ตัวอย่าง: สเปกบอกว่า POST /tasks คืน 201 พร้อม {id,title} คุณเรียก API แล้วได้ 200 พร้อม {id,title,createdAt} นั่นไม่ใช่ "ใกล้เคียง" หากคุณสร้าง SDK อัตโนมัติจากสเปก

ก่อนแก้ไขอะไร ให้ตัดสินใจวิธีแก้ความขัดแย้ง:\n

  • ถ้าพฤติกรรมถูกแต่ไม่มีเอกสาร: แก้สเปก\n- ถ้าสเปกเป็นสัญญาที่ตกลงไว้: แก้โค้ดให้ตรง\n- ถ้าไม่มีอันไหนถูก: เปลี่ยนพฤติกรรมที่ต้องการก่อน แล้วอัปเดตทั้งสอง\n เก็บการเปลี่ยนแปลงให้เล็กและรีวิวได้: ทีละ endpoint ทีละการตอบกลับ ทีละการแก้ schema ง่ายกว่าตรวจสอบและรีเทสต์

ผลิตตัวอย่างการตรวจสอบฝั่งลูกค้าและฝั่งเซิร์ฟเวอร์จากสเปก

เมื่อมีสเปกที่วางใจได้ ให้แปลงมันเป็นตัวอย่างการตรวจสอบเล็กๆ นี่คือสิ่งที่หยุด drift ไม่ให้กลับมา

การตรวจสอบฝั่งเซิร์ฟเวอร์ (ปฏิเสธคำขอที่ไม่ถูกต้อง)

ฝั่งเซิร์ฟเวอร์คือการล้มเหลวอย่างรวดเร็วเมื่อคำขอไม่ตรงสัญญา และคืนข้อผิดพลาดชัดเจน นั่นช่วยปกป้องข้อมูลและทำให้บั๊กหาง่ายขึ้น

วิธีง่ายๆ ในการแสดงตัวอย่างการตรวจสอบฝั่งเซิร์ฟเวอร์คือตั้งเป็นเคสที่มีสามส่วน: input, expected output, และ expected error (รหัสหรือรูปแบบข้อความ ไม่ใช่ข้อความเป๊ะๆ)

ตัวอย่าง (สัญญาบอกว่า title จำเป็นและมีความยาว 1 ถึง 120 ตัวอักษร):

{
  "name": "Create task without title returns 400",
  "request": {"method": "POST", "path": "/tasks", "body": {"title": ""}},
  "expect": {"status": 400, "body": {"error": {"code": "VALIDATION_ERROR"}}}
}

การตรวจสอบฝั่งไคลเอนต์ (จับการเปลี่ยนแปลงก่อนผู้ใช้)

ฝั่งไคลเอนต์คือการตรวจจับ drift ก่อนผู้ใช้ หากเซิร์ฟเวอร์เริ่มคืนรูปร่างต่างไป หรือฟิลด์จำเป็นหาย เทสต์ของคุณควรแจ้งเตือน

เก็บเช็กฝั่งลูกค้าโฟกัสที่สิ่งที่คุณพึ่งพาจริง เช่น “งานมี id, title, status.” หลีกเลี่ยงการยืนยันทุกฟิลด์ตัวเลือกหรือการเรียงลำดับที่แน่นอน คุณอยากได้ล้มเมื่อมีการเปลี่ยนแปลงที่ทำให้พัง ไม่ใช่เมื่อมีฟิลด์เสริมที่ไม่เป็นอันตราย

แนวทางที่ทำให้เทสต์อ่านง่าย:\n

  • ตรวจ presence และ type มากกว่าค่าแบบเป๊ะๆ\n- ยืนยันฟิลด์ที่จำเป็นเท่านั้น เว้นแต่ฟิลด์ตัวเลือกสำคัญจริงๆ\n- สำหรับข้อผิดพลาด ให้เช็กสถานะและรหัสข้อผิดพลาด ไม่ใช่ข้อความทั้งข้อความ\n- ยอมให้มีฟิลด์เพิ่มได้ ยกเว้นสัญญาระบุห้ามไว้\n ถ้าคุณใช้ Koder.ai คุณสามารถสร้างและเก็บเคสตัวอย่างเหล่านี้ไว้ข้างไฟล์ OpenAPI แล้วอัปเดตพร้อมกับการแก้สเปกในการรีวิวเดียวกัน

ตัวอย่างสถานการณ์: Tasks API แบบง่ายตั้งแต่ต้นจนจบ

เพิ่มการตรวจสอบสัญญาอย่างรวดเร็ว
สร้างตัวอย่างการตรวจสอบฝั่งเซิร์ฟเวอร์และฝั่งลูกค้าเล็กๆ เพื่อจับ drift ก่อน
สร้างการทดสอบ

นึกภาพ API เล็กๆ มีสาม endpoint: POST /tasks สร้างงาน, GET /tasks แสดงรายการ, และ GET /tasks/{id} คืนงานหนึ่งรายการ

เริ่มจากเขียนตัวอย่างคอนกรีตสำหรับหนึ่ง endpoint เหมือนอธิบายให้ผู้ทดสอบฟัง

สำหรับ POST /tasks พฤติกรรมที่ตั้งใจอาจเป็น:

  • สำเร็จ: ส่ง { "title": "Buy milk" } แล้วได้ 201 พร้อมวัตถุ task ใหม่ รวม id, title, และ done:false\n- ล้มเหลว 1: ส่ง {} แล้วได้ 400 พร้อมข้อผิดพลาดแบบ { "error": "title is required" }\n- ล้มเหลว 2: ส่ง { "title": "x" } (สั้นเกินไป) แล้วได้ 422 กับ { "error": "title must be at least 3 characters" }\n เมื่อ Claude Code ร่าง OpenAPI ส่วนนี้ ควรจับ schema, รหัสสถานะ, และตัวอย่างที่สมจริง:
paths:
  /tasks:
    post:
      summary: Create a task
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTaskRequest'
            examples:
              ok:
                value: { "title": "Buy milk" }
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
              examples:
                created:
                  value: { "id": "t_123", "title": "Buy milk", "done": false }
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                missingTitle:
                  value: { "error": "title is required" }
        '422':
          description: Unprocessable Entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                tooShort:
                  value: { "error": "title must be at least 3 characters" }

ความไม่ตรงกันที่พบบ่อยมักละเอียด: API ที่รันคืน 200 แทนที่จะเป็น 201, หรือคืน { "taskId": 123 } แทน { "id": "t_123" } นั่นคือความต่างแบบ “เกือบเหมือน” ที่ทำให้ไคลเอนต์ที่สร้างอัตโนมัติพัง

แก้โดยเลือกความจริงแหล่งเดียว ถ้าพฤติกรรมที่ตั้งใจถูกต้อง ให้เปลี่ยนการใช้งานให้คืน 201 และรูปแบบ Task ที่ตกลงไว้ ถ้าการใช้งานในโปรดักชันถูกพึ่งพาอยู่แล้ว ให้อัปเดตสเปก (และบันทึกพฤติกรรม) ให้ตรงกับความเป็นจริง แล้วเพิ่มการตรวจสอบและการตอบข้อผิดพลาดที่ขาดไป

ความผิดพลาดทั่วไปที่ทำให้สัญญาไม่ซื่อสัตย์

สัญญาจะไม่ซื่อสัตย์เมื่อมันหยุดอธิบายกฎ และเริ่มอธิบายสิ่งที่ API คืนในวันดีๆ วันเดียว ทดสอบง่ายๆ: implementation ใหม่สามารถผ่านสเปกนี้โดยไม่ต้องคัดลอกความพิสดารของวันนี้หรือไม่?

กับดักหนึ่งคือ overfitting คุณจับการตอบกลับเดียวแล้วทำให้เป็นกฎ ตัวอย่าง: API ปัจจุบันคืน dueDate: null สำหรับทุกงาน ดังนั้นสเปกบอกว่าฟิลด์ nullable แต่กฎจริงอาจเป็น “จำเป็นเมื่อ status เป็น scheduled.” สัญญาควรแสดงกฎ ไม่ใช่แค่ dataset ปัจจุบัน

ข้อผิดพลาดคือส่วนที่ซื่อสัตย์มักพัง มักอยากสเปกเฉพาะการตอบกลับสำเร็จเพราะดูสะอาด แต่ไคลเอนต์ต้องการพื้นฐาน: 401 เมื่อโทเค็นหาย, 403 เมื่อไม่ได้สิทธิ์, 404 สำหรับ ID ไม่รู้จัก, และข้อผิดพลาดการตรวจสอบที่สม่ำเสมอ (400 หรือ 422) อย่าละเลย

รูปแบบอื่นที่ก่อปัญหา:\n

  • ชื่อและชนิดที่เบี่ยงแต่ละ endpoint (taskId ที่ route หนึ่งแต่ id ในอีกที่หนึ่ง, หรือ priority เป็น string ที่ตอบกลับหนึ่งและเป็น number อีกที่)\n- ตัวอย่างขัดแย้งกับสคีมา (enum ไม่ตรง, ตัวอย่าง date-time ไม่ใช่ ISO 8601)\n- ชนิดถูกขยายกว้างเพื่อเลี่ยงการตัดสินใจ (ทุกอย่างกลายเป็น string, ทุกอย่างเป็น optional)\n- สเปกอ่านเหมือนคัดลอกการตลาด (“เร็ว”, “ปลอดภัย”) แทนที่จะเป็นสัญญาที่ทดสอบได้

สัญญาที่ดีต้องทดสอบได้ ถ้าคุณเขียนเทสต์ที่ล้มจากสเปกไม่ได้ แปลว่ายังไม่ซื่อสัตย์พอ

การตรวจเช็ครวดเร็วก่อนแชร์หรือเผยแพร่ไฟล์ OpenAPI

สร้าง OpenAPI ให้สะอาดขึ้น
ร่างสเปก OpenAPI 3.1 ที่สอดคล้อง มีตัวอย่าง และสถานะโค้ดที่สม่ำเสมอ
สร้างสเปก

ก่อนส่งไฟล์ OpenAPI ให้ทีมอื่น (หรือวางในเอกสาร) ให้ทำผ่านด่วนว่า “คนอื่นใช้ได้โดยไม่ต้องอ่านหัวใจฉันไหม?”

เริ่มจากตัวอย่าง สเปกอาจถูกต้องแต่ยังไร้ประโยชน์ถ้าคำขอและการตอบกลับทุกอันเป็นนามธรรม สำหรับแต่ละ operation ให้มีอย่างน้อยหนึ่งตัวอย่างคำขอจริงและหนึ่งตัวอย่างการตอบกลับสำเร็จ สำหรับข้อผิดพลาด ให้มีตัวอย่างหนึ่งตัวอย่างต่อความล้มเหลวยอดนิยม (auth, validation)

แล้วตรวจความสอดคล้อง หาก endpoint หนึ่งคืน { "error": "..." } และอีก endpoint คืน { "message": "..." } ไคลเอนต์จะมีโลจิกแยกทางมากเกินไป เลือกรูปร่างข้อผิดพลาดเดียวและใช้ซ้ำ พร้อมรหัสสถานะที่คาดเดาได้

เช็คลิสต์สั้นๆ:\n

  • ฟิลด์ที่จำเป็น รูปแบบ (email, uuid, date-time) และ enums ระบุชัดเจน\n- รหัสสถานะมีเจตนาและสอดคล้องกันข้าม endpoint ที่คล้ายกัน\n- ข้อผิดพลาดมีทั้ง schema และตัวอย่าง ไม่ใช่แค่สถานะ\n- เรียกใช้งานจริง 2-3 ครั้งต่อ endpoint (เทสต์, curl, Postman หรือจาก logs) และเปรียบเทียบ payload กับสเปก\n- คุณสามารถเขียนคำเรียกไคลเอนต์เล็กๆ จากสเปกโดยไม่เดาหัวข้อ header, ชื่อฟิลด์, หรือ nullability

ทริคปฏิบัติ: เลือก endpoint หนึ่ง แกล้งเป็นคนไม่เคยเห็น API แล้วตอบว่า “ฉันส่งอะไร ได้อะไรกลับ และอะไรพัง?” ถ้า OpenAPI ตอบไม่ได้ แปลว่ายังไม่พร้อม

ขั้นตอนถัดไป: ทำให้เป็นนิสัย (และรักษาการเปลี่ยนแปลงให้ปลอดภัย)

เวิร์กโฟลว์นี้ให้ผลเมื่อทำเป็นประจำ ไม่ใช่แค่ตอน release ให้วิธีง่ายๆ และยึดถือมัน: รันเมื่อ endpoint เปลี่ยน และรันอีกครั้งก่อนเผยแพร่สเปกที่อัปเดต

เก็บความเป็นเจ้าของให้ง่าย คนที่เปลี่ยน endpoint เป็นผู้แก้บันทึกพฤติกรรมและร่างสเปก ผู้ตรวจทานอีกคนหนึ่งรีวิว diff ระหว่างสเปกกับการใช้งานเหมือนการรีวิวโค้ด QA หรือทีมซัพพอร์ตมักเป็นผู้ตรวจที่ดีเพราะเห็นการตอบกลับที่ไม่ชัดเจนและกรณีขอบได้เร็ว

ปฏิบัติต่อการแก้สัญญาเหมือนแก้โค้ด ถ้าคุณใช้ตัวสร้างที่ขับด้วยแชทอย่าง Koder.ai ให้ถ่าย snapshot ก่อนแก้เสี่ยงและใช้ rollback หากจำเป็น Koder.ai ยังรองรับการส่งออกซอร์ส ซึ่งช่วยให้เก็บสเปกและการใช้งานให้อยู่ด้วยกันในรีโปได้ง่ายขึ้น

กิจวัตรที่มักได้ผลโดยไม่ทำให้ทีมช้าลง:\n

  • เขียนบันทึกพฤติกรรมเมื่อเพิ่ม endpoint ใหม่\n- ตรวจสอบสเปกและรันเทสต์สัญญาก่อน merge\n- เปรียบเทียบสเปกกับ API ที่รันก่อน release\n- ถ่าย snapshot ก่อนแก้เสี่ยง; rollback ถ้า diff ทำให้สับสน\n การกระทำถัดไป: เลือก endpoint หนึ่งที่มีอยู่แล้ว เขียนบันทึกพฤติกรรม 5-10 บรรทัด (อินพุต ผลลัพธ์ กรณีข้อผิดพลาด), สร้างร่าง OpenAPI จากบันทึกนั้น, ตรวจสอบมัน, แล้วเปรียบเทียบกับการใช้งานจริง แก้ความไม่ตรงกันหนึ่งอย่าง ทดสอบใหม่ แล้วทำซ้ำ หลังทำ endpoint เดียว นิสัยนี้มักติด

คำถามที่พบบ่อย

What does “OpenAPI drift” mean in plain terms?

OpenAPI drift คือกรณีที่ API ที่รันจริงไม่ตรงกับไฟล์ OpenAPI ที่แชร์กัน Spec อาจขาดฟิลด์ใหม่ๆ รหัสสถานะ (status codes) หรือกฎการยืนยันตัวตน (auth) หรืออาจอธิบายพฤติกรรม "ในอุดมคติ" ที่เซิร์ฟเวอร์ไม่ได้ทำตาม\n\nเรื่องนี้สำคัญเพราะไคลเอนต์ (แอป บริการอื่น SDK ที่สร้างอัตโนมัติ หรือเทสต์) ตัดสินใจตามสัญญา ไม่ใช่ตามสิ่งที่เซิร์ฟเวอร์ของคุณ "มักจะ" ทำ

What are the most common ways drift shows up for client teams?

การแตกต่างจะปรากฏในการใช้งานจริงอย่างสุ่มและยากต่อการดีบัก: แอปมือถือคาดหวัง 201 แต่ได้ 200, SDK ไม่สามารถ deserialize ตอบกลับเพราะฟิลด์ถูกเปลี่ยนชื่อ, หรือการจัดการข้อผิดพลาดล้มเหลวเพราะรูปแบบข้อผิดพลาดไม่ตรงกัน\n\nแม้เมื่อไม่มีการชน แอปทีมก็จะเริ่มไม่ไว้ใจสเปก และหยุดใช้งานไฟล์นั้น ซึ่งทำให้ระบบเตือนล่วงหน้าหายไป

Why shouldn’t I start the OpenAPI spec by copying backend code?

เพราะโค้ดสะท้อนพฤติกรรมปัจจุบัน รวมทั้งความผิดพลาดหรือรายละเอียดเล็กๆ ที่คุณอาจไม่อยากสัญญาต่อไป\n\nวิธีที่ดีกว่า: เขียนพฤติกรรมที่ต้องการก่อน (อินพุต เอาต์พุต ข้อผิดพลาด) แล้วตรวจสอบให้การใช้งานตรงตามสเปก แบบนี้จะได้สัญญาที่คุณบังคับใช้ได้ แทนที่จะเป็นภาพชั่วขณะของ routes วันนี้

What’s the minimum “behavior notes” I should write per endpoint?

สำหรับแต่ละ endpoint ให้เก็บ:\n\n- Purpose: ทำอะไรในหนึ่งประโยค\n- Auth: ต้องใช้โทเค็น/บทบาทหรือสาธารณะ\n- Request: query/path params, headers, และตัวอย่าง body เป็น JSON\n- Responses: อย่างน้อยหนึ่งตัวอย่างความสำเร็จและหนึ่งหรือสองตัวอย่างข้อผิดพลาดจริงที่มีรหัสสถานะ\n- Edge cases: ID หาย/ไม่ถูกต้อง ซ้ำ (409?) ผลลัพธ์ว่าง ขอบเขตการแบ่งหน้า\n\nถ้าคุณเขียนคำร้องขอที่ชัดเจนและสองตัวอย่างตอบกลับ คุณมักมีข้อมูลพอที่จะร่างสเปกที่เป็นความจริงได้

How do I keep error responses consistent across the whole spec?

เลือกหนึ่งรูปแบบของ body ข้อผิดพลาดและนำมาใช้ซ้ำทั่วทั้งสเปก\n\nค่าพื้นฐานที่เรียบง่ายหนึ่งในสองแบบคือ:\n\n- { "error": "message" } หรือ\n- { "error": { "code": "...", "message": "...", "details": ... } }\n\nจากนั้นใช้แบบเดียวกันในทุก endpoint และในตัวอย่าง ความสม่ำเสมอสำคัญกว่าความซับซ้อนเพราะไคลเอนต์มักโค้ดรูปแบบนี้ไว้

How can I prompt Claude Code so it doesn’t make up endpoints or fields?

ให้ Claude Code ได้รับบันทึกพฤติกรรมของคุณและกฎเข้มงวด และบอกให้มันอย่าคิดขึ้นเอง แนวทางปฏิบัติที่ใช้ได้จริง:\n\n- “Source of truth is the behavior notes. Do not guess.”\n- “If unclear, add TODO in the spec and list it under ASSUMPTIONS.”\n- “Include reusable schemas (like Error) and reference them.”\n- “Use consistent naming (PascalCase schemas, lowerCamelCase fields).”\n\nหลังการสร้าง ให้ตรวจสอบรายการ ASSUMPTIONS ก่อน นั่นคือที่ที่ความซื่อสัตย์อาจพังถ้าคุณยอมรับการเดา

What should I check in the OpenAPI file before I compare it to the running API?

ตรวจสอบสเปกก่อนเทียบกับโปรดักชัน:\n\n- ฟิลด์ที่จำเป็น vs ที่ไม่จำเป็น ถูกต้องหรือไม่\n- รูปแบบระบุชัดเจน (UUID, email, ISO 8601 date-time)\n- ตัวอย่างสอดคล้องกับ schemas (enums, types, nullability)\n- รหัสสถานะตั้งใจและสอดคล้อง (เช่น create มักเป็น 201)\n- ข้อกำหนดการยืนยันตัวตนระบุไว้ต่อ endpoint\n\nการตรวจสอบเหล่านี้จะจับความหวังลมๆ แล้งๆ ใน OpenAPI ก่อนที่คุณจะเทียบกับการทำงานจริง

When the spec and the running API disagree, which one should I change?

มองการใช้งานจริงเป็นสิ่งที่ผู้ใช้เจอวันนี้ แล้วตัดสินแต่ละความขัดแย้ง:\n\n- ถ้าพฤติกรรมถูกแต่ไม่มีในเอกสาร: อัปเดตสเปก\n- ถ้าสเปกเป็นสัญญาที่ตกลงกันไว้: แก้โค้ดให้ตรง\n- ถ้าไม่มีอันไหนถูก: เปลี่ยนพฤติกรรมที่ต้องการก่อน, แล้วอัปเดตทั้งสองฝั่ง\n\nเก็บการเปลี่ยนแปลงให้เล็ก (หนึ่ง endpoint หรือการปรับ schema ครั้งละหนึ่งอย่าง) เพื่อทดสอบซ้ำได้ง่าย

What do “server-side” vs “client-side” contract validation checks look like?

ฝั่งเซิร์ฟเวอร์: ปฏิเสธคำขอที่ละเมิดสัญญาและส่งข้อผิดพลาดที่ชัดเจนและสม่ำเสมอ (status + error code/shape)\n\nฝั่งไคลเอนต์: ตรวจจับการเปลี่ยนรูปแบบการตอบกลับก่อนผู้ใช้จะพบ โดยยืนยันเฉพาะสิ่งที่คุณพึ่งพาจริงๆ:\n\n- ฟิลด์ที่จำเป็นมีอยู่และชนิดถูกต้อง\n- รหัสสถานะตรงตามโฟลว์ที่คาดไว้\n- ข้อผิดพลาดมีรูปแบบที่ตกลงกัน\n\nหลีกเลี่ยงการยืนยันทุกฟิลด์ที่เป็นตัวเลือกเพื่อให้เทสต์ล้มเมื่อมีการเปลี่ยนแปลงที่ทำให้เกิดปัญหา ไม่ใช่เพราะเพิ่มฟิลด์ใหม่ที่ไม่เป็นอันตราย

What’s a simple habit to prevent drift from coming back?

กิจวัตรที่ใช้ได้จริงคือ:\n\n- อัปเดตบันทึกพฤติกรรมและสเปกเมื่อเพิ่ม endpoint ใหม่\n- ตรวจสอบ OpenAPI (schemas, ตัวอย่าง, รหัสสถานะ, auth) ก่อน merge\n- เปรียบเทียบตัวอย่าง request/response จริงกับสเปกก่อน release\n- เก็บตัวอย่างการตรวจสอบเล็กๆ ในเทสต์เพื่อจับ drift อัตโนมัติ\n\nถ้าคุณใช้ Koder.ai คุณสามารถเก็บไฟล์ OpenAPI ไว้กับโค้ด ใช้ snapshot ก่อนแก้เสี่ยง และ rollback ได้เมื่อจำเป็น

สารบัญ
ทำไมสัญญา OpenAPI ถึงเบี่ยง (และทำไมเรื่องนี้ถึงสำคัญ)เริ่มจากพฤติกรรมที่ต้องการ ไม่ใช่จากโค้ดเทมเพลตน้ำหนักเบาสำหรับอธิบาย endpointsร่างสเปก OpenAPI ด้วย Claude Code (prompt แบบที่ใช้ได้)ตรวจสอบสเปกก่อนเทียบกับ API ที่รันจริงเปรียบเทียบสเปกกับการใช้งาน API ที่รันจริงผลิตตัวอย่างการตรวจสอบฝั่งลูกค้าและฝั่งเซิร์ฟเวอร์จากสเปกตัวอย่างสถานการณ์: Tasks API แบบง่ายตั้งแต่ต้นจนจบความผิดพลาดทั่วไปที่ทำให้สัญญาไม่ซื่อสัตย์การตรวจเช็ครวดเร็วก่อนแชร์หรือเผยแพร่ไฟล์ OpenAPIขั้นตอนถัดไป: ทำให้เป็นนิสัย (และรักษาการเปลี่ยนแปลงให้ปลอดภัย)คำถามที่พบบ่อย
แชร์
Koder.ai
Build your own app with Koder today!

The best way to understand the power of Koder is to see it for yourself.

Start FreeBook a Demo