จะออกแบบ API ปลายทางสำหรับโพสต์ออบเจ็กต์ลูกและเพื่อให้ได้ลูกทั้งหมดของผู้ปกครองทั้งหมดได้อย่างไร


12

ตัวอย่างเช่นฉันมีเอนทิตี: ลูกค้า, รายงาน ลูกค้าอาจมีหลายรายงานและฉันคิดว่าจุดสิ้นสุดสำหรับการจัดการรายงานเดียวควรซ้อนกันเช่นนี้

/clients/{client_id}/reports/{report_id}

สำหรับรายงานทั้งหมดของลูกค้าหนึ่งรายคาดว่าจะเป็น enpoint:

/clients/{client_id}/reports

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

แนวทางของฉัน:

  1. (ฉันเห็นมันในบาง google api) ใช้ "-" แทนและแยกเป็น "ทั้งหมด":

/clients/-/reports

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

  1. สร้างจุดปลายแยกเฉพาะสำหรับรายงานทั้งหมด:

/reports

แต่เพื่อรับรายงานลูกค้าก็ยัง:

/clients/{client_id}/reports

  1. Refactor endpoints เพื่อทำให้ "client" ไม่ใช่ parent แต่เป็นเพียงพารามิเตอร์ตัวกรอง:

/reports?client={client_id} - รายงานลูกค้าหนึ่งราย

/reports - รายงานของลูกค้าทั้งหมด

ในกรณีของการเพิ่มจุดปลายใหม่สำหรับการโพสต์รายงานสำหรับลูกค้าที่เฉพาะเจาะจงมันอาจดูน่าเกลียดเพราะมันจะเป็นคำขอ POST กับพารามิเตอร์ใน URL

มีคำแนะนำอื่น ๆ เกี่ยวกับความคิดหรือไม่?


2
คุณอาจจะสนใจคำถาม
เลฟ

คำตอบ:


3

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

ก่อนอื่นโปรดจำไว้ว่าไม่มีกฎทองคำสำหรับการสร้างแบบจำลอง RESTful API ทั้งหมดที่เรามีคือแนวปฏิบัติและแบบแผนที่ดีที่สุด ดังที่ได้กล่าวไปแล้วคำตอบที่น่าจะเป็น - ตามปกติ - เลือกคำตอบที่ตรงกับความต้องการของคุณมากที่สุดและในกรณีนี้คำตอบที่แสดงแบบจำลองของคุณได้ดีที่สุด

ดังนั้นตรวจสอบสามตัวเลือกจากความหมาย

# 1 เครื่องหมาย "-"

นี่คือความคิดที่สดใส จะช่วยให้เราสามารถแสดงเงื่อนไขทั้งหมดreportsclientsที่อยู่ใน มัน จำกัด การ "ค้นหา" ให้แคบลงไปยังชุดของรายงานที่เฉพาะเจาะจง(ที่อยู่ในclientsขอบเขต)

มันเก็บความคิดของลำดับชั้น (เป็นของ) ตลอดเวลาดังนั้นหากreportsสามารถพบได้ในสถานที่ต่าง ๆ สัญกรณ์นี้ทำให้เป็นเรื่องใหญ่ ตัวอย่างเช่น:

  • รายงานทั้งหมดที่เป็นของลูกค้า /clients/-/reports
  • รายงานทั้งหมดที่เป็นของแผนก /departments/-/reports
  • รายงานทั้งหมดที่เป็นของพนักงาน /employees/-/reports

อย่างไรก็ตามสำหรับการดึงรายงานทั้งหมดที่มีอยู่ในระบบการรักษาลำดับชั้นไม่ได้ให้ประโยชน์ที่มีคุณค่าใด ๆ เหนือตัวเลือกถัดไป

# 2 URI ที่แตกต่างกัน

หากเราไม่ต้องการแสดงขอบเขต / บริบท / ลำดับชั้นในเวลาที่เรียกรายงานที่มีอยู่ทั้งหมดวิธีนี้ดูเหมือนจะสมเหตุสมผลกว่าสำหรับฉัน

URI ใหม่ ( /reports) ยังเปิดโอกาสการจัดการรายงานอีกด้วย อย่างไรก็ตามเราไม่จำเป็นต้องให้การสนับสนุน RESTful อย่างสมบูรณ์หากเราไม่เห็นว่าจำเป็น Make a separate endpoint just for all the reportsตัวอย่างเช่นคุณได้ระบุไว้ ไม่เป็นไรคุณจะต้องนำไปใช้GETและอาจจะมีบางตัวกรองสำหรับการสืบค้นและนั่นก็คือ

/reports?client={client_id}โปรดทราบว่าคุณยังคงสามารถทำเช่นนี้ การมี URI ที่แตกต่างกันสำหรับทรัพยากรเดียวกันนั้นใช้ได้ บางบทความที่ฉันได้อ่านจะเรียกความแข็งแกร่งนี้

# 3 ย้อนกลับลำดับชั้น

ฉันรู้สึกว่าวิธีนี้ไม่เป็นไปตามที่คุณคาดหวัง นอกจากนี้ฉันคิดว่ามันจะนำคุณไปสู่จุดเริ่มต้นในที่สุด

สรุปผลการวิจัย

โปรดทราบว่า # 1 และ # 2 ไม่ได้เกิดขึ้นพร้อมกัน เราสามารถใช้ทั้งสองอย่าง ด้วยสถานการณ์จริงและจากสถานที่ OP 'ฉันจะดำเนินการเพียง # 2


1: เทียบเท่ากับที่/clients/-/reportsฉันเดา


0

รูปแบบการออกแบบ API ของ Google แนะนำให้ใช้ '-' ในสถานการณ์นี้

GET /clients/-/reports

ที่มา:

https://cloud.google.com/apis/design/design_patterns#list_sub-collections


2
ไกลออกไปไม่ว่าจะเป็นสำหรับผมที่จะไม่เห็นด้วยกับผู้ทรงอำนาจ Google แต่ฉันคิดว่าฉันต้องการสิ่งที่ชอบ /client/{client_id}/report/{report_id}และ/clients/report/{report_id}
โรเบิร์ตฮาร์วีย์

2
@ RobertHarvey ทำไมไม่เพียงแค่/reports?
Laiv

@Laiv: นั่นจะหมายถึงรายงานทั้งหมด รีเฟรชหน้าของคุณ ฉันแก้ไขนินจาแล้ว
Robert Harvey

@RobertHarvey ฉันหมายความว่าทำไมไม่ 2 ปลายทางที่แตกต่างกันและ/clients... /reports
Laiv

1
@Laiv: ตกลง แต่นั่นทำให้เกิดคำถามขึ้นมาว่า "ฉันควรใส่พารามิเตอร์อะไรในเนื้อหาของคำขอ"
Robert Harvey
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.