พารามิเตอร์ API มักมีโครงสร้างที่ซับซ้อน โดยที่เอนด์พอยต์เดียวรองรับการรวมพารามิเตอร์ที่แตกต่างกันหลายชุด ตัวอย่างเช่น เอนด์พอยต์การเข้าสู่ระบบอาจรองรับการยืนยันตัวตนด้วยชื่อผู้ใช้-รหัสผ่าน, อีเมล-รหัสผ่าน หรือรหัสยืนยันทางโทรศัพท์ เอนด์พอยต์การชำระเงินสามารถเสนอวิธีการต่างๆ เช่น บัตรเครดิต, WeChat Pay หรือ Alipay ซึ่งแต่ละวิธีต้องการฟิลด์ที่แตกต่างกัน

แนวทางการจัดทำเอกสาร API แบบดั้งเดิมมักจะเพียงแค่แสดงรายการฟิลด์ที่เป็นไปได้ทั้งหมดและใช้คำอธิบายข้อความเช่น "เลือกฟิลด์ที่แตกต่างกันตามสถานการณ์ที่แตกต่างกัน" แนวทางนี้ไม่แม่นยำและไม่เป็นมิตรกับนักพัฒนา ซึ่งมักนำไปสู่ความสับสน Apidog รองรับคุณสมบัติ oneOf, anyOf และ allOf ของ JSON Schema ช่วยให้คุณสามารถอธิบายโครงสร้างข้อมูลที่ซับซ้อนเหล่านี้ได้อย่างแม่นยำในเอกสาร API ของคุณ
ทำความเข้าใจโหมดการรวมสามโหมด
ใน JSON Schema, oneOf, anyOf และ allOf ใช้เพื่อรวมซับสกีมาหลายตัวเข้าด้วยกัน แต่มีความหมายเชิงตรรกะที่แตกต่างกัน:
- allOf: รวมกฎหลายข้อเข้าด้วยกัน โดยกำหนดให้ทั้งหมดต้องตรงกัน
- anyOf: กำหนดให้ต้องตรงกันอย่างน้อยหนึ่งรายการ สามารถตรงกันได้หลายรายการ
- oneOf: ต้องตรงกับสกีมาเพียงหนึ่งเดียวเท่านั้น การตรงกับศูนย์หรือหลายสกีมาจะถือว่าไม่ผ่าน
การตั้งค่าโหมดการรวมใน Apidog
Apidog มีสองวิธีในการใช้โหมดการรวมเหล่านี้:
แนวทางการใช้ Visual Editor
วิธีแรกใช้แผงการแก้ไขแบบภาพ ในโปรเจกต์ของคุณ ให้คลิก "Data Models" เพื่อสร้างโมเดลใหม่ จากนั้นค้นหา "Combination Modes" ในการเลือกประเภท เลือกโหมด oneOf, anyOf หรือ allOf ที่ต้องการ จากนั้นกำหนดโครงสร้างข้อมูลเฉพาะสำหรับแต่ละซับสกีมา

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

การนำรูปแบบเหล่านี้ไปใช้ในเอนด์พอยต์ API
เมื่อคุณกำหนดโมเดลข้อมูลของคุณแล้ว คุณสามารถนำไปใช้ในเอกสาร API ของคุณได้ เมื่อแก้ไขพารามิเตอร์คำขออินเทอร์เฟซ ให้เลือกประเภท Body เป็น JSON จากนั้นในส่วนโครงสร้างข้อมูล คุณสามารถอ้างอิง "Data Models" ที่คุณเพิ่งสร้าง หรือเลือก "Combination Modes" โดยตรงเพื่อกำหนดโครงสร้างพารามิเตอร์ที่ซับซ้อน

หลักการเดียวกันนี้ใช้กับการกำหนดข้อมูลการตอบกลับ เมื่อเพิ่มตัวอย่างการตอบกลับในส่วนการตอบกลับ คุณสามารถใช้โหมดการรวมเพื่ออธิบายรูปแบบการตอบกลับสำหรับสถานการณ์ที่แตกต่างกัน ด้วยวิธีนี้ นักพัฒนาสามารถเข้าใจได้อย่างชัดเจนว่าโครงสร้างข้อมูลใดจะถูกส่งคืนในสถานการณ์ที่แตกต่างกัน
กรณีการใช้งานจริง
allOf: การรวมโครงสร้างหลายรายการ
allOf รวมโครงสร้างหลายรายการเข้าด้วยกัน – ไม่ใช่เกี่ยวกับการเลือก แต่เกี่ยวกับการซ้อนทับ allOf ไม่ได้เปลี่ยนลำดับชั้นของฟิลด์ ฟิลด์ทั้งหมดจะอยู่ในออบเจกต์เดียวกัน มันเพียงแค่ซ้อนทับกฎหลายข้อบนข้อมูลเดียวกัน คิดว่ามันเป็น "ตรรกะ AND" – ข้อจำกัดของโครงสร้างย่อยทั้งหมดจะต้องเป็นไปตามที่กำหนด
ตัวอย่างเช่น JSON Schema นี้:
{
"allOf": [
{
"description": "Basic user information",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
},
"required": ["id", "name"]
},
{
"description": "Contact information",
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"phone": { "type": "string" }
},
"required": ["email"]
}
]
}
สกีมานี้หมายความว่า: ข้อมูลสุดท้ายจะต้องเป็นไปตามโครงสร้าง "ข้อมูลผู้ใช้พื้นฐาน" และ "ข้อมูลติดต่อ" พร้อมกัน
กล่าวอีกนัยหนึ่งคือ เนื้อหาคำขอต้องมี id, name และ email ส่วน phone เป็นทางเลือก
ข้อมูลที่ถูกต้อง:
{
"id": 1001,
"name": "John Doe",
"email": "john@example.com",
"phone": "1-800-000-0000"
}
ข้อมูลที่ไม่ถูกต้อง:
{
"id": 1001,
"name": "John Doe"
}
ข้อมูลนี้ขาดฟิลด์ email ที่จำเป็นและไม่เป็นไปตามโครงสร้างที่สอง
แนวทางนี้เหมาะสำหรับการแบ่งออบเจกต์ที่ซับซ้อน ข้อมูลผู้ใช้, รายละเอียดคำสั่งซื้อ, รายการการตั้งค่า ฯลฯ ทั้งหมดสามารถแบ่งออกเป็นโครงสร้างอิสระตามโมดูลการทำงาน จากนั้นนำมารวมกันโดยใช้ allOf อินเทอร์เฟซอื่นๆ ที่ต้องการส่วนหนึ่งของโครงสร้างเหล่านี้สามารถอ้างอิงได้โดยตรงโดยไม่ต้องมีการกำหนดซ้ำซ้อน
anyOf: การเป็นไปตามเงื่อนไขอย่างน้อยหนึ่งข้อ
anyOf แสดงรายการโครงสร้างที่เป็นไปได้หลายรายการ และข้อมูลจะถือว่าถูกต้องตราบใดที่เป็นไปตามอย่างน้อยหนึ่งในนั้น ไม่สนใจว่าเงื่อนไขหลายข้อจะตรงกันหรือไม่ และไม่จำเป็นต้องมีการจับคู่ที่ไม่ซ้ำกัน
ตัวอย่างเช่น ฟิลด์ตัวระบุอาจเป็นอีเมลหรือหมายเลขโทรศัพท์ รูปแบบทั้งสองนี้แตกต่างกันอย่างชัดเจน แต่ทั้งคู่จัดอยู่ในหมวดหมู่ของ "ข้อมูลประจำตัวผู้ใช้สำหรับการเข้าสู่ระบบ"
คุณสามารถใช้ anyOf เพื่อแสดงเจตนา "สามารถเป็น A หรือ B" ได้อย่างชัดเจน:
{
"type": "object",
"properties": {
"identifier": {
"description": "User identifier: can be email or phone number",
"anyOf": [
{
"title": "Email format",
"description": "Must be a valid email address",
"type": "string",
"format": "email"
},
{
"title": "Phone format",
"description": "Must be a valid international phone number",
"type": "string",
"pattern": "^\\+?[1-9]\\d{1,14}$"
}
]
},
"password": {
"type": "string",
"minLength": 6,
"description": "Login password, at least 6 characters"
}
},
"required": ["identifier", "password"],
"description": "User login request parameters"
}
โครงสร้างนี้หมายความว่า: ตัวระบุเป็นสตริงที่ถือว่าถูกต้องตราบใดที่เป็นไปตามรูปแบบอีเมลหรือรูปแบบหมายเลขโทรศัพท์
ข้อมูลที่ถูกต้อง:
{
"identifier": "test@example.com",
"password": "123456"
}
{
"identifier": "+1-800-000-0000",
"password": "123456"
}
ข้อมูลที่ไม่ถูกต้อง:
{
"identifier": "abc",
"password": "123456"
}
"abc" ไม่ใช่อีเมลและไม่ใช่รูปแบบหมายเลขโทรศัพท์ที่ถูกต้อง ไม่เป็นไปตามเงื่อนไขใดๆ
oneOf: เลือกเพียงหนึ่งตัวเลือกเท่านั้น
oneOf แสดงรายการโครงสร้างที่เป็นไปได้หลายรายการ และข้อมูลจะต้องเป็นไปตามหนึ่งในนั้นเท่านั้น เน้นความพิเศษเฉพาะ – คุณสามารถเลือกได้เพียงหนึ่งเดียวเท่านั้น ไม่มากไปกว่านั้น ไม่น้อยไปกว่านั้น
ตัวอย่างเช่น วิธีการชำระเงิน: ในการชำระเงิน ผู้ใช้ต้องเลือกหนึ่งในบัตรเครดิต, WeChat Pay หรือ Alipay แต่ไม่สามารถใช้วิธีการสองวิธีพร้อมกันได้ และไม่สามารถเลือกไม่ใช้วิธีใดเลย คุณสามารถกำหนดตรรกะ "เลือกหนึ่งเดียว" นี้โดยใช้ oneOf:
{
"properties": {
"paymentMethod": {
"description": "Payment method, must choose exactly one",
"oneOf": [
{
"title": "Credit Card Payment",
"description": "Pay with credit card, requires card number and expiry date",
"type": "object",
"properties": {
"type": { "const": "credit_card" },
"cardNumber": { "type": "string" },
"expiryDate": { "type": "string" }
},
"required": ["type", "cardNumber", "expiryDate"],
"additionalProperties": false
},
{
"title": "WeChat Pay",
"description": "Pay through WeChat, requires user's openid",
"type": "object",
"properties": {
"type": { "const": "wechat" },
"openid": { "type": "string" }
},
"required": ["type", "openid"],
"additionalProperties": false
},
{
"title": "Alipay Payment",
"description": "Pay through Alipay, requires account ID",
"type": "object",
"properties": {
"type": { "const": "alipay" },
"accountId": { "type": "string" }
},
"required": ["type", "accountId"],
"additionalProperties": false
}
]
}
}
}
คำจำกัดความนี้หมายความว่า: paymentMethod เป็นออบเจกต์ที่สามารถจับคู่กับโครงสร้างย่อยสามโครงสร้างได้เพียงหนึ่งเดียวเท่านั้น
ตัวอย่างที่ถูกต้อง:
{
"paymentMethod": {
"type": "wechat",
"openid": "wx_123456"
}
}
{
"paymentMethod": {
"type": "credit_card",
"cardNumber": "4111111111111111",
"expiryDate": "12/25"
}
}
ตัวอย่างที่ไม่ถูกต้อง:
{
"paymentMethod": {
"type": "wechat",
"openid": "wx_123",
"accountId": "2088102"
}
}
แม้ว่าประเภทจะเป็น "wechat" การมี accountId อาจทำให้มันตรงกับหลายโครงสร้าง ทำให้ oneOf ไม่ผ่าน การเพิ่ม "additionalProperties": false ป้องกันความสับสนนี้ (หมายถึงไม่อนุญาตให้มีฟิลด์เพิ่มเติม) ทำให้มั่นใจว่าแต่ละโครงสร้างอนุญาตเฉพาะฟิลด์ที่กำหนดเองเท่านั้น Apidog รองรับการกำหนดค่าด้วยภาพสำหรับ additionalProperties
เมื่อคุณต้องการเลือกเฉพาะเจาะจงระหว่างประเภทที่แตกต่างกันหลายประเภท oneOf เป็นวิธีที่ตรงไปตรงมาและน่าเชื่อถือที่สุดในการแสดงสิ่งนี้
การเลือกโหมดการรวมที่เหมาะสม
การเลือกโหมดการรวมส่วนใหญ่ขึ้นอยู่กับตรรกะทางธุรกิจของคุณ:
- ใช้ allOf เมื่อคุณต้องการรวมและสืบทอดรูปแบบหลายรูปแบบ
- ใช้ anyOf เมื่อคุณต้องการการรวมทางเลือกที่ยืดหยุ่น
- ใช้ oneOf เมื่อคุณต้องการการเลือกที่เฉพาะเจาะจงอย่างเข้มงวด
การทำความเข้าใจบทบาทของแต่ละส่วนช่วยให้เอกสาร API ของคุณสามารถอธิบายโครงสร้างข้อมูลที่ซับซ้อนได้อย่างแม่นยำ ทำให้ผู้ใช้อินเทอร์เฟซเข้าใจได้ทันทีว่าจะส่งพารามิเตอร์อย่างไร
สรุป
การรองรับ JSON Schema ที่ครอบคลุมของ Apidog ช่วยให้นักพัฒนาสามารถสร้างเอกสาร API ที่แม่นยำและชัดเจนสำหรับโครงสร้างพารามิเตอร์ที่ซับซ้อนที่สุดได้ ด้วยการใช้การรวม oneOf, anyOf และ allOf คุณสามารถขจัดความกำกวมและให้คำแนะนำที่ชัดเจนแก่ผู้ใช้ API
พร้อมที่จะสัมผัสพลังของเอกสาร API ขั้นสูงแล้วหรือยัง? ลองใช้ Apidog วันนี้และดูว่าการจัดการพารามิเตอร์ API ที่ซับซ้อนด้วยความแม่นยำและชัดเจนนั้นง่ายดายเพียงใด
