ข้ามไปเนื้อหาหลัก

ข้อผิดพลาดและการแบ่งหน้า

รูปแบบข้อผิดพลาด รหัสสถานะที่จะพบ และวิธีแบ่งหน้าของ endpoint รายการ

รูปแบบการห่อข้อมูล (envelope)

endpoint ส่วนใหญ่ห่อข้อมูลไว้ในคีย์ data

json
{
  "success": true,
  "data": { "id": 1, "name": "Widget" }
}

งานเขียนที่ไม่มีข้อมูลจะคืน จะตอบเป็นข้อความแทน — เช่นการแก้ไข (PATCH) ส่วนใหญ่

json
{ "success": true, "message": "Update Success" }

แต่มีบางกลุ่ม — ผู้ติดต่อ เอกสารขาย และข้อมูลองค์กร — ที่คืน object ตรง ๆ โดยไม่ห่อด้วย data

json
{ "id": 1, "documentNumber": "IV-2026-0001", "documentType": "IV" }

และการลบจะตอบ 204 No Content โดยไม่มี body

เนื่องจากรูปแบบต่างกันตามกลุ่ม endpoint ควรเขียนไคลเอนต์ให้ตรวจรูปร่างของข้อมูล ไม่ใช่สมมติว่าเป็นแบบเดียว

ts
// ใช้ได้ทั้งกับ { data: T } และ T เปล่า ๆ
function unwrap<T>(body: unknown): T {
  if (body && typeof body === "object" && "data" in body) {
    return (body as { data: T }).data;
  }
  return body as T;
}

หน้าคู่มือของแต่ละ endpoint ระบุไว้ว่ากลุ่มนั้นคืนรูปแบบใด

รูปแบบข้อผิดพลาด

ทุก 4xx และ 5xx ใช้ body รูปแบบเดียวกัน

json
{
  "statusCode": 400,
  "errorCode": "BadRequest",
  "errorMessage": "invalid request",
  "errorDescription": "issueDate must be YYYY-MM-DD",
  "errorValidation": [
    {
      "field": "DocumentType",
      "tag": "oneof",
      "message": "documentType must be one of: QT, SO, IV, RE, CS, CN, DN"
    }
  ]
}
ฟิลด์หมายเหตุ
statusCodeตรงกับ HTTP status
errorCodeรหัสที่เครื่องอ่านได้และคงที่ — ให้แยกเงื่อนไขด้วยค่านี้ ไม่ใช่ด้วยข้อความ
errorMessageข้อความสั้น แปลตาม Accept-Language นำไปแสดงให้ผู้ใช้ได้
errorDescriptionรายละเอียดเพิ่มเติมสำหรับนักพัฒนา มีเฉพาะบางกรณี
errorValidationหนึ่งรายการต่อหนึ่งฟิลด์ที่ไม่ผ่าน มีเฉพาะข้อผิดพลาดด้านการตรวจสอบข้อมูล

errorValidation[].field เป็นชื่อฟิลด์ในโครงสร้างฝั่งเซิร์ฟเวอร์ (DocumentType) ไม่ใช่ชื่อคีย์ JSON (documentType) หากต้องการแมปกลับไปที่ payload ให้เปลี่ยนอักษรตัวแรกเป็นตัวเล็ก (และเปลี่ยน ID เป็น Id เมื่อมี) สำหรับฟิลด์ที่เป็น enum อย่าง documentType ตัว message จะระบุค่าที่ยอมรับไว้ให้เลย เช่น "documentType must be one of: QT, SO, IV, RE, CS, CN, DN"

รหัสสถานะ

รหัสความหมายควรทำอะไร
200อ่านหรือแก้ไขสำเร็จ—
201สร้างข้อมูลสำเร็จเก็บ id ที่คืนมา
204ลบสำเร็จไม่มีข้อมูลให้อ่าน
400payload ไม่ผ่านการตรวจสอบ หรือการดำเนินการนั้นทำกับเอกสารนี้ไม่ได้แก้ payload และดู errorValidation
401ไม่มีคีย์ คีย์ผิดรูปแบบ ถูกเพิกถอน หรือหมดอายุดูการยืนยันตัวตน
403องค์กรของคีย์นี้ไม่มีสิทธิ์ทำรายการนี้ตรวจว่าคีย์เป็นขององค์กรที่ถูกต้อง
404ไม่พบข้อมูล หรือข้อมูลไม่ได้อยู่ในองค์กรนี้อย่าตีความว่า "ถูกลบแล้ว" อาจไม่เคยเป็นข้อมูลของคุณเลย
409ข้อมูลขัดแย้ง เช่น ลบสิ่งที่ยังถูกอ้างอิงอยู่จัดการการอ้างอิงนั้นก่อน
429เรียกถี่เกินโควตารอตามค่า Retry-After
500ข้อผิดพลาดฝั่งเซิร์ฟเวอร์งานอ่าน retry ได้ งานเขียนให้ตรวจก่อน (ดูหัวข้อ retry ในBase URL และการจำกัดอัตราการเรียก)

ค่า errorCode ที่ควรจัดการเป็นกรณีเฉพาะ

  • InvalidStatusTransition — เปลี่ยนสถานะจากสถานะปัจจุบันของเอกสารนี้ไม่ได้ ดูข้อมูลอ้างอิงชนิดเอกสาร
  • JournalEntryImbalanced — ยอดเดบิตและเครดิตของรายการบัญชีไม่เท่ากัน
  • OpenAPIRateLimitExceeded — เรียกเกินโควตาต่อคีย์

การแบ่งหน้า

endpoint รายการทุกตัวรับพารามิเตอร์สองตัวเดียวกัน

พารามิเตอร์ค่าเริ่มต้นหมายเหตุ
page1เริ่มนับจาก 1
limit20สูงสุด 100 ค่าที่มากกว่านั้นจะถูกลดลงมา ไม่ใช่ถูกปฏิเสธ

และตอบกลับด้วย items พร้อมบล็อก pagination

json
{
  "items": [ { "id": 41 }, { "id": 40 } ],
  "pagination": {
    "previousPage": null,
    "currentPage": 1,
    "nextPage": 2,
    "totalPages": 10,
    "totalRows": 195
  }
}
  • previousPage และ nextPage เป็น null เมื่อถึงต้นหรือปลายช่วง นี่คือสัญญาณให้หยุด และตรวจง่ายกว่าการเทียบ currentPage กับ totalPages
  • totalRows คือจำนวนรวมทุกหน้า ไม่ใช่จำนวนในหน้านี้
  • โปรดจำว่าสินค้า เอกสารซื้อ เรื่องเบิกค่าใช้จ่าย และรายการบัญชี จะซ้อนทั้งก้อนนี้ไว้ใน data ขณะที่ผู้ติดต่อและเอกสารขายคืนที่ระดับบนสุด

วนอ่านทุกหน้า

bash
page=1
while [ -n "$page" ] && [ "$page" != "null" ]; do
  body=$(curl -sS "$ABSERP_API_URL/openapi/v1/sales/documents?type=IV&limit=100&page=$page" \
    -H "Authorization: Bearer $ABSERP_API_KEY")
  echo "$body" | jq -c '.items[]'
  page=$(echo "$body" | jq -r '.pagination.nextPage')
done

สองเรื่องที่ควรระวังเวลาวนอ่าน

  • ใช้ขนาดหน้าที่ใหญ่ที่สุดที่ระบบคุณรับได้ (limit=100) จำนวน request ที่น้อยลงหมายถึงโควตาที่ใช้ไปน้อยลง
  • ข้อมูลอาจเปลี่ยนระหว่างที่อ่านแต่ละหน้า สำหรับงาน export กลางคืน ให้กรองด้วยช่วงวันที่ปิดแล้ว (fromDate / toDate) เพื่อไม่ให้ข้อมูลใหม่ดันแถวไปอยู่ในหน้าที่คุณอ่านผ่านไปแล้ว

สอง endpoint ที่ไม่แบ่งหน้า

GET /chart-of-accounts และ GET /warehouses คืนอาร์เรย์ธรรมดา เพราะเป็นรายการขนาดเล็กและมีจำนวนจำกัด ทั้งสองจะไม่สนใจ page และ limit

ขั้นตอนถัดไป

อ่านต่อที่ เอกสารขาย