Claude Code สำหรับการสร้างโครงร่าง Go API: กำหนดรูปแบบ handler-service-error แบบเดียว แล้วสร้าง endpoints ใหม่ที่คงรูปแบบเดียวกันทั่วทั้ง API ของคุณ

Go API มักเริ่มสะอาด: มีเพียงไม่กี่ endpoint คนทำงานหนึ่งหรือสองคน และทุกอย่างอยู่ในหัวของทุกคน จากนั้น API ขยาย ฟีเจอร์ถูกปล่อยภายใต้ความกดดัน และความแตกต่างเล็ก ๆ จะคืบคลานเข้ามา แต่ละอย่างดูไม่เป็นอันตราย แต่รวมกันแล้วจะทำให้การเปลี่ยนแปลงในอนาคตช้าลง
ตัวอย่างทั่วไป: handler ตัวหนึ่งถอดรหัส JSON เป็น struct และคืน 400 พร้อมข้อความที่เป็นประโยชน์ อีกตัวคืน 422 ในรูปแบบต่างออกไป และตัวที่สามบันทึกข้อผิดพลาดในฟอร์แมตคนละแบบ สิ่งเหล่านี้ไม่ทำให้คอมไพล์ล้มเหลว แต่สร้างการตัดสินใจเล็กน้อยและการแก้ไขเล็ก ๆ ทุกครั้งที่คุณเพิ่มอะไรใหม่
คุณจะรู้สึกถึงความยุ่งในที่ต่าง ๆ เช่น:
CreateUser, AddUser, RegisterUser) ทำให้การค้นหายากขึ้น"Scaffolding" ในที่นี้หมายถึงเทมเพลตที่ทำซ้ำได้สำหรับงานใหม่: โค้ดวางที่ไหน แต่ละเลเยอร์ทำอะไร และการตอบเป็นอย่างไร มันไม่ใช่แค่การสร้างโค้ดจำนวนมาก แต่เป็นการตรึงรูปแบบให้คงที่
เครื่องมืออย่าง Claude สามารถช่วย scaffold endpoints ใหม่ได้เร็ว แต่จะมีประโยชน์ต่อเมื่อคุณถือรูปแบบเป็นกฎ คุณเป็นคนกำหนดกฎ คุณรีวิวทุก diff และคุณรันทดสอบ โมเดลเติมส่วนมาตรฐาน; มันไม่ควรเปลี่ยนสถาปัตยกรรมของคุณ
API ใน Go จะเติบโตได้ง่ายเมื่อทุกคำขอเดินตามเส้นทางเดียวกัน ก่อนที่คุณจะเริ่มสร้าง endpoint ให้เลือกการแบ่งเลเยอร์แบบหนึ่งและยึดมั่นกับมัน
งานของ handler คือ HTTP เท่านั้น: อ่านคำขอ, เรียก service, และเขียนการตอบ มันไม่ควรมี business rules, SQL, หรือ "กรณีพิเศษนี้เท่านั้น" ของ logic
service เป็นเจ้าของ use case: กฎธุรกิจ การตัดสินใจ และการประสานงานระหว่าง repositories หรือการเรียกภายนอก มันไม่ควรรู้เรื่อง HTTP เช่น status codes, headers, หรือวิธีการเรนเดอร์ข้อผิดพลาด
data access (repository/store) เป็นเจ้าของรายละเอียดการเก็บข้อมูล มันแปลงเจตนาของ service เป็น SQL/queries/transactions และไม่ควรกำหนดกฎธุรกิจเกินความสมบูรณ์ของข้อมูลพื้นฐาน และไม่ควรแต่งรูปแบบการตอบ API
เช็คลิสต์การแยกชั้นที่เป็นประโยชน์:
เลือกกฎข้อเดียวและอย่ายืดมัน
แนวทางง่าย ๆ:
ตัวอย่าง: handler ตรวจสอบว่า email มีและดูเหมือนอีเมล ส่วน service ตรวจสอบว่าอีเมลนั้นอนุญาตและยังไม่ถูกใช้
ตัดสินใจตั้งแต่ต้นว่า service คืน domain types หรือ DTOs
ค่าเริ่มต้นที่สะอาดคือ: handlers ใช้ request/response DTOs, services ใช้ domain types, และ handler แมป domain ไปเป็น response นั่นทำให้ service คงที่แม้ว่าสัญญา HTTP จะเปลี่ยน
ถ้าการแมปหนักเกินไป ให้ยึดไว้เหมือนเดิม: ให้ service คืน domain type พร้อม typed error และเก็บการจัดรูปแบบ JSON ไว้ใน handler
ถ้าคุณต้องการให้ endpoints ที่สร้างขึ้นดูเหมือนคนเดียวกัน ให้ล็อกรูปแบบข้อผิดพลาดตั้งแต่ต้น การสร้างจะดีที่สุดเมื่อรูปแบบผลลัพธ์ไม่สามารถต่อรองได้: รูป JSON เดียว แผนผังรหัสสถานะเดียว และกฎเดียวสำหรับสิ่งที่จะเปิดเผย
เริ่มด้วยซองข้อผิดพลาดเดียวที่ทุก endpoint คืนเมื่อเกิดความล้มเหลว เก็บมันให้เล็กและคาดเดาได้:
{
"code": "validation_failed",
"message": "One or more fields are invalid.",
"details": {
"fields": {
"email": "must be a valid email address",
"age": "must be greater than 0"
}
},
"request_id": "req_01HR..."
}
ใช้ code สำหรับเครื่อง (คงที่และคาดเดาได้) และ message สำหรับมนุษย์ (สั้นและปลอดภัย) ใส่ข้อมูลโครงสร้างเพิ่มเติมใน details สำหรับ validation แผนผัง details.fields แบบเรียบง่ายสร้างได้ง่ายและไคลเอนต์สามารถแสดงใกล้ช่องป้อนข้อมูลได้ง่าย
ต่อมา เขียนแผนผังรหัสสถานะและยึดตามมัน ยิ่งถกเถียงน้อยต่อ endpoint ยิ่งดี ถาคุณต้องการทั้ง 400 และ 422 ให้แยกอย่างชัดเจน:
bad_json -> 400 Bad Request (malformed JSON)validation_failed -> 422 Unprocessable Content (well-formed JSON, invalid fields)not_found -> 404 Not Foundconflict -> 409 Conflict (duplicate key, version mismatch)unauthorized -> 401 Unauthorizedforbidden -> 403 Forbiddeninternal -> 500 Internal Server Errorตัดสินใจว่าสิ่งใดจะถูกเก็บไว้ในล็อกกับสิ่งใดจะคืนกลับให้ไคลเอนต์ กฎที่ดีคือ: ไคลเอนต์ได้ข้อความที่ปลอดภัยและ request ID; ล็อกเก็บข้อผิดพลาดเต็มรูปแบบและบริบทภายใน (SQL, upstream payloads, user IDs) ที่คุณไม่อยากเปิดเผย
สุดท้าย ให้มาตรฐาน request_id ยอมรับ header ของ ID ที่มาจากภายนอกถ้ามี (จาก API gateway) มิฉะนั้นให้สร้างขึ้นที่ขอบ (middleware) แนบมันกับ context, ใส่ไว้ในล็อก และคืนมันในทุกการตอบข้อผิดพลาด
ถ้าคุณต้องการให้ scaffolding คงที่ โครงโฟลเดอร์ต้องน่าเบื่อและทำซ้ำได้ Generators ตามรูปแบบที่เห็นได้ แต่จะลอยเมื่อไฟล์กระจัดกระจายหรือชื่อเปลี่ยนไปตามฟีเจอร์
เลือกการตั้งชื่อแบบเดียวและอย่ายืดมัน เลือกคำเดียวสำหรับแต่ละสิ่งและรักษา: handler, service, repo, request, response ถ้า route เป็น POST /users ให้ตั้งชื่อไฟล์และ types รอบ ๆ users และ create (อย่าใช้บางครั้ง register, บางครั้ง addUser)
โครงแบบเรียบง่ายที่ตรงกับเลเยอร์ปกติ:
internal/
httpapi/
handlers/
users_handler.go
services/
users_service.go
data/
users_repo.go
apitypes/
users_types.go
ตัดสินใจว่าประเภทที่ใช้ร่วมกันอยู่ที่ไหน เพราะตรงนี้มักทำให้โปรเจกต์ยุ่งเกินไป หนึ่งกฎที่มีประโยชน์:
internal/apitypes (ตรงกับ JSON และความต้องการ validation)ถ้าประเภทมี JSON tags และออกแบบมาสำหรับไคลเอนต์ ให้ถือว่ามันเป็น API type
เก็บ dependencies ของ handler ให้ขั้นต่ำและทำให้กฎนั้นชัดเจน:
เขียนเอกสาร pattern สั้น ๆ ที่ root ของ repo (ใช้ Markdown ธรรมดาก็พอ) รวม tree ของโฟลเดอร์ กฎการตั้งชื่อ และตัวอย่าง flow เล็ก ๆ (handler -> service -> repo และแต่ละส่วนอยู่ไฟล์ไหน) นี่คือเอกสารอ้างอิงที่คุณวางใน generator เพื่อให้ endpoints ใหม่ตรงตามโครงสร้างทุกครั้ง
ก่อนที่จะสร้างสิบ endpoints ให้สร้าง endpoint หนึ่งตัวที่คุณเชื่อถือ นี่คือมาตรฐาน: ไฟล์ที่คุณชี้ให้เห็นและบอกว่า "โค้ดใหม่ต้องดูแบบนี้" คุณสามารถเขียนจากศูนย์หรือรีแฟกเตอร์ตัวที่มีอยู่จนมันตรง
เก็บ handler ให้บาง หนึ่งเทคนิคที่ช่วยได้มาก: ใส่ interface ระหว่าง handler กับ service เพื่อให้ handler ขึ้นกับ contract ไม่ใช่ struct ที่เป็นคอนกรีต
เพิ่มคอมเมนต์สั้น ๆ ใน reference endpoint เฉพาะจุดที่โค้ดที่สร้างอาจสะดุด อธิบายการตัดสินใจ (ทำไม 400 vs 422, ทำไม create คืน 201, ทำไมซ่อน internal errors ด้วยข้อความทั่วไป) ข้ามคอมเมนต์ที่แค่บอกซ้ำโค้ด
เมื่อ reference endpoint ทำงานแล้ว ให้ดึง helpers ออกมาเพื่อให้ endpoint ใหม่มีโอกาส drift น้อยที่สุด helpers ที่นำกลับมาใช้ซ้ำได้มากที่สุดมักเป็น:
นี่คือตัวอย่างว่า "handler บาง + interface" รูปแบบจะเป็นอย่างไรในทางปฏิบัติ:
type UserService interface {
CreateUser(ctx context.Context, in CreateUserInput) (User, error)
}
func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
var in CreateUserRequest
if err := BindJSON(r, &in); err != nil {
WriteError(w, ErrBadJSON) // 400: malformed JSON
return
}
if err := Validate(in); err != nil {
WriteError(w, err) // 422: validation details
return
}
user, err := h.svc.CreateUser(r.Context(), in.ToInput())
if err != nil {
WriteError(w, err)
return
}
WriteJSON(w, http.StatusCreated, user)
}
ล็อกมันโดยมีเทสต์เล็ก ๆ สองสามตัว (แม้แต่ table test สำหรับการแมปข้อผิดพลาด) การสร้างทำงานได้ดีที่สุดเมื่อมีเป้าหมายเดียวที่สะอาดให้เลียนแบบ
ความสม่ำเสมอเริ่มจากสิ่งที่คุณวางเข้าไปและสิ่งที่คุณห้าม สำหรับ endpoint ใหม่ ให้ให้สองสิ่ง:
รวม handler, method ของ service, request/response types, และ helpers ร่วมที่ endpoint ใช้ แล้วระบุสัญญาเป็นคำง่าย ๆ:
POST /v1/widgets)ระบุชัดเจนว่าสิ่งใดต้องตรง: การตั้งชื่อ, paths ของ package, และ helper functions (WriteJSON, BindJSON, WriteError, validator ของคุณ)
พรอมพ์ที่เข้มงวดจะป้องกันการ "ปรับสถาปัตยกรรมโดยไม่ตั้งใจ" ตัวอย่าง:
Using the reference endpoint below and the pattern notes, generate a new endpoint.
Contract:
- Route: POST /v1/widgets
- Request: {"name": string, "color": string}
- Response: {"id": string, "name": string, "color": string, "createdAt": string}
- Errors: invalid JSON -> 400; validation -> 422; duplicate name -> 409; unexpected -> 500
Output ONLY these files:
1) internal/http/handlers/widgets_create.go
2) internal/service/widgets.go (add method only)
3) internal/types/widgets.go (add types only)
Do not change: router setup, existing error format, existing helpers, or unrelated files.
Must use: package paths and helper functions exactly as in the reference.
ถ้าคุณใช้เทสต์ ให้ขอเทสต์อย่างชัดเจน (และตั้งชื่อไฟล์ทดสอบ) มิฉะนั้นโมเดลอาจข้ามมันหรือแต่ง setup การทดสอบขึ้นมาเอง
ทำ quick diff หลังการสร้าง ถ้ามันแก้ไข helpers ร่วม, การลงทะเบียน router, หรือรูปแบบข้อผิดพลาดที่มีอยู่ ให้ปฏิเสธผลลัพธ์และกำหนด "ห้ามเปลี่ยน" ให้เข้มงวดขึ้น
ผลลัพธ์สม่ำเสมอเท่ากับข้อมูลนำเข้า ใช้วิธีพรอมพ์เดียวทุกครั้งโดยมีบริบทเล็ก ๆ จาก repo
คัดลอก วาง และเติมช่องว่าง:
You are editing an existing Go HTTP API.
CONTEXT
- Folder tree (only the relevant parts):
<paste a small tree: internal/http, internal/service, internal/repo, etc>
- Key types and patterns:
- Handler signature style: <example>
- Service interface style: <example>
- Request/response DTOs live in: <package>
- Standard error response JSON:
{
"error": {
"code": "invalid_argument",
"message": "...",
"details": {"field": "reason"}
}
}
- Status code map:
invalid_json -> 400
invalid_argument -> 422
not_found -> 404
conflict -> 409
internal -> 500
TASK
Add a new endpoint: <METHOD> <PATH>
- Handler name: <Name>
- Service method: <Name>
- Request JSON example:
{"name":"Acme"}
- Success response JSON example:
{"id":"123","name":"Acme"}
CONSTRAINTS
- No new dependencies.
- Keep functions small and single-purpose.
- Match existing naming, folder layout, and error style exactly.
- Do not refactor unrelated files.
ACCEPTANCE CHECKS
- Code builds.
- Existing tests pass (add tests only if the repo already uses them for handlers/services).
- Run gofmt on changed files.
FINAL INSTRUCTION
Before writing code, list any assumptions you must make. If an assumption is risky, ask a short question instead.
วิธีนี้บังคับสามสิ่ง: บล็อกบริบท (สิ่งที่มีอยู่), บล็อกข้อจำกัด (สิ่งที่ห้ามทำ), และตัวอย่าง JSON ที่เป็นรูปธรรม (เพื่อไม่ให้รูปแบบคลาดเคลื่อน) คำสั่งสุดท้ายเป็นมาตรการความปลอดภัย: ถ้าโมเดลไม่แน่ใจ ให้ถามก่อนจะเขียนโค้ด
สมมติคุณต้องการเพิ่ม endpoint "Create project" เป้าหมายคือรับชื่อ บังคับกฎบางอย่าง เก็บข้อมูล และคืน ID ใหม่ จุดยุ่งยากคือการรักษาการแยก handler-service-repo และรูปแบบข้อผิดพลาดเดิม
โฟลว์ที่สอดคล้องกันคือ:
นี่คือคำขอที่ handler รับ:
{ "name": "Roadmap", "owner_id": "u_123" }
เมื่อสำเร็จ คืน 201 Created ID ควรมาจากที่เดียวเสมอ เช่น ให้ Postgres สร้างแล้ว repo คืนมันกลับ:
{ "id": "p_456", "name": "Roadmap", "owner_id": "u_123", "created_at": "2026-01-09T12:34:56Z" }
สองเส้นทางล้มเหลวที่สมจริง:
ถ้า validation ล้มเหลว (ชื่อหายหรือสั้นเกินไป) คืน field-level error โดยใช้รูปแบบมาตรฐานและรหัสสถานะที่เลือก:
{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid request", "details": { "name": "must be at least 3 characters" } } }
ถ้าชื่อต้องเป็นเอกลักษณ์ต่อ owner และ service พบโปรเจกต์ที่มีอยู่แล้ว ให้คืน 409 Conflict:
{ "error": { "code": "PROJECT_NAME_TAKEN", "message": "Project name already exists", "details": { "name": "Roadmap" } } }
หนึ่งการตัดสินใจที่ช่วยให้รูปแบบสะอาด: handler ตรวจสอบ "รูปแบบคำขอนี้ถูกต้องไหม?" ในขณะที่ service เป็นเจ้าของ "อนุญาตไหม?" การแยกนี้ทำให้ endpoint ที่สร้างได้คาดเดาได้
วิธีที่เร็วที่สุดที่จะเสีย consistency คือปล่อยให้ generator สร้างตามใจ
ความคลาดเคลื่อนทั่วไปคือรูปแบบข้อผิดพลาดใหม่ Endpoint หนึ่งคืน {error: "..."}, อีกหนึ่งคืน {message: "..."}, และอีกตัวเพิ่ม nested object แก้ปัญหานี้โดยเก็บซองข้อผิดพลาดเดียวและแผนผังรหัสสถานะไว้ที่เดียว แล้วบังคับให้ endpoints ใหม่ใช้ผ่าน import path และชื่อฟังก์ชัน ถ้า generator เสนอ field ใหม่ ให้ถือว่าเป็นการเปลี่ยน API ไม่ใช่ความสะดวก
อีกการ drift คือ handler บวม: เริ่มจากเล็ก ๆ validate แล้วตรวจสิทธิ์ แล้ว query DB แล้ว branch ตามกฎธุรกิจ ในไม่ช้าทุก handler จะดูต่างกัน ให้กฎเดียว: handlers แปลง HTTP เป็น typed inputs/outputs; services เป็นเจ้าของการตัดสินใจ; data access เป็นเจ้าของ queries
การตั้งชื่อที่ไม่สอดคล้องกันก็สะสมเช่นกัน ถ้า endpoint หนึ่งใช้ CreateUserRequest และอีกอันใช้ NewUserPayload คุณจะเสียเวลาไล่หา types และเขียน glue ปฏิเสธชื่อใหม่เว้นแต่มีเหตุผลชัดเจน
อย่าส่ง raw database errors กลับให้ไคลเอนต์ นอกจากจะรั่วรายละเอียดแล้ว ยังทำให้ข้อความและรหัสสถานะไม่สม่ำเสมอ ห่อข้อผิดพลาดภายใน บันทึกสาเหตุ แล้วคืน public error code ที่เสถียร
หลีกเลี่ยงการเพิ่มไลบรารี "เพื่อความสะดวก" ทุกชิ้นที่เพิ่มเข้ามาจะกลายเป็นสไตล์ที่ต้องตามให้ตรง
เกราะป้องกันที่ป้องกันการเสียหายได้ส่วนใหญ่:
ถ้าไม่สามารถ diff สอง endpoint แล้วเห็นรูปแบบเดียวกัน (imports, flow, error handling) ให้เข้มงวดกับ prompt และสร้างใหม่ก่อน merge
ก่อน merge อะไรที่สร้าง ตรวจสอบโครงสร้างก่อน ถ้ารูปแบบถูกต้อง บั๊กเชิงตรรกะจะหาได้ง่ายกว่า
การเช็กโครงสร้าง:
request_id เดิมการเช็กพฤติกรรม:
not found หรือ conflict) และยืนยัน HTTP status และ JSON shapeปฏิบัติต่อ pattern เป็นสัญญาร่วม ไม่ใช่รสนิยม เก็บเอกสาร "วิธีการสร้าง endpoints" ไว้ใกล้โค้ด และรักษา reference endpoint ตัวเดียวที่แสดงแนวทางแบบครบวงจร
ขยายการสร้างเป็นชุดเล็ก ๆ สร้าง 2–3 endpoint ที่ครอบคลุมเงื่อนไขต่าง ๆ (อ่านง่าย, สร้างพร้อม validation, อัปเดตพร้อม not-found) แล้วหยุดและปรับปรุง ถ้าการรีวิวยังเจอ drift เดิม ๆ ให้ปรับ baseline doc และ reference endpoint ก่อนสร้างเพิ่ม
วัฏจักรที่ทำซ้ำได้:
ถ้าต้องการวงจร build-review ที่เข้มข้นขึ้น แพลตฟอร์ม vibe-coding อย่าง Koder.ai (koder.ai) สามารถช่วยคุณ scaffold และวนปรับได้เร็วใน workflow แชท แล้วส่งออกซอร์สเมื่อเข้ากับมาตรฐาน ความสำคัญไม่ได้อยู่ที่เครื่องมือเท่านั้น แต่คือกฎ: baseline ต้องเป็นผู้กำกับของงาน
ล็อกเทมเพลตซ้ำได้ตั้งแต่ต้น: แยกชั้นแบบสม่ำเสมอ (handler → service → data access), ใช้ซองข้อผิดพลาดเดียว และแผนผังรหัสสถานะเดียว จากนั้นใช้ “reference endpoint” ตัวเดียวเป็นตัวอย่างที่ทุก endpoint ใหม่ต้องทำตาม
ให้ handler ทำงานเฉพาะด้าน HTTP:
ถ้าพบ SQL, การตรวจสิทธิ์ หรือ branching ของธุรกิจใน handler ให้ย้ายไปที่ service
ใส่ business rules และการตัดสินใจไว้ใน service:
Service ควรคืนผลลัพธ์แบบ domain และ typed errors—ไม่ควรมี HTTP status codes หรือการจัดรูปแบบ JSON
แยกความกังวลเรื่อง persistence ออกไป:
หลีกเลี่ยงการเข้ารหัสรูปแบบการตอบ API หรือบังคับกฎธุรกิจใน repo นอกจากเรื่องความสมบูรณ์ของข้อมูลพื้นฐาน
ค่าเริ่มต้นที่เรียบง่าย:
ตัวอย่าง: handler ตรวจสอบว่า email มีและดูเหมือนอีเมล; service ตรวจสอบว่าอนุญาตและยังไม่ถูกใช้
ใช้ซองข้อผิดพลาดมาตรฐานเดียวทั่วทั้ง API และรักษาให้นิ่ง รูปร่างที่ใช้งานได้ปกติคือ:
code สำหรับเครื่อง (คงที่)message สำหรับมนุษย์ (สั้นและปลอดภัย)details สำหรับข้อมูลโครงสร้างเพิ่มเติม (เช่น field errors)request_id สำหรับการติดตามวิธีนี้ช่วยให้ไคลเอนต์ไม่ต้องเขียนกรณีพิเศษและทำให้ endpoint ที่สร้างโดยอัตโนมัติคาดเดาได้
จดแผนผังรหัสสถานะและใช้เสมอ ตัวอย่างการแยก:
ส่งกลับข้อผิดพลาดสาธารณะที่ปลอดภัยและสม่ำเสมอ แล้วบันทึกรายละเอียดจริงไว้ในล็อก:
code คงที่, message สั้น, และ request_idวิธีนี้ป้องกันการรั่วของข้อมูลภายในและหลีกเลี่ยงข้อความข้อผิดพลาดที่แตกต่างกันแบบสุ่มตาม endpoint
สร้าง endpoint “ทองคำ” (golden) ตัวเดียวที่คุณเชื่อถือและบังคับให้ endpoint ใหม่ต้องเหมือนมัน:
BindJSON, WriteJSON, WriteError, ฯลฯ)จากนั้นเพิ่มเทสต์ขนาดเล็กอีกสองสามตัว (แม้แต่ table tests สำหรับการแมปข้อผิดพลาด) เพื่อยึดแนวทาง
ให้โมเดลบริบทและข้อจำกัดที่เข้มงวด:
หลังการสร้าง ปฏิเสธ diff ที่ “ปรับสถาปัตยกรรม” แทนที่จะทำตาม baseline
ป้องกันไม่ให้ generator หยุดนิ่ง:
ถ้าไม่สามารถ diff สอง endpoint แล้วเห็นรูปแบบเดียวกัน ให้เข้มงวดกับ prompt และสร้างใหม่ก่อนยอมรับ
เช็กโครงสร้างก่อน merge:
request_id เดิมเช็กพฤติกรรม:
ปฏิบัติตามวัฏจักรเล็ก ๆ:
ถ้าต้องการวงจร build-review ที่เข้มข้นขึ้น แพลตฟอร์ม vibe-coding อย่าง Koder.ai (koder.ai) จะช่วยสเกลการ scaffold และวนปรับใน workflow แชท แล้วส่งออกซอร์สโค้ดเมื่อเข้ากับมาตรฐานได้ แต่สิ่งที่สำคัญกว่าคือกฎ: baseline ต้องเป็นผู้กำกับ
400 สำหรับ JSON ผิดรูป (bad_json)422 สำหรับ validation ล้มเหลว (validation_failed)404 สำหรับทรัพยากรไม่พบ (not_found)409 สำหรับความขัดแย้ง (duplicate/version mismatch)500 สำหรับความล้มเหลวที่ไม่คาดคิดกุญแจคือความสม่ำเสมอ: อย่าโต้แย้งกันเป็นราย endpoint
not found หรือ conflict) และยืนยัน status/JSON