เป็นครั้งแรก
ตามRFC 3986 §3.4 (Uniform Resource Identifiers § (ส่วนประกอบไวยากรณ์) | Query
3.4 การค้นหา
องค์ประกอบแบบสอบถามประกอบด้วยข้อมูลที่ไม่เป็นลำดับชั้นซึ่งรวมถึงข้อมูลในส่วนประกอบเส้นทาง (ส่วน 3.3) ทำหน้าที่ระบุทรัพยากรภายในขอบเขตของแบบแผนของ URI และอำนาจการตั้งชื่อ (ถ้ามี)
ส่วนประกอบของแบบสอบถามมีไว้สำหรับดึงข้อมูลที่ไม่ใช่แบบลำดับชั้น มีบางสิ่งที่เป็นลำดับชั้นในธรรมชาติมากกว่าต้นไม้ตระกูล! Ergo ไม่ว่าคุณจะคิดว่ามันเป็น "REST-y" หรือไม่ก็ตามเพื่อให้เป็นไปตามรูปแบบโปรโตคอลและกรอบงานและสำหรับการพัฒนาระบบบนอินเทอร์เน็ตคุณจะต้องไม่ใช้สตริงข้อความค้นหาเพื่อระบุข้อมูลนี้
REST ไม่เกี่ยวข้องกับคำจำกัดความนี้
ก่อนที่จะตอบคำถามเฉพาะของคุณพารามิเตอร์การสืบค้น "ค้นหา" นั้นมีชื่อไม่ดี ดีกว่าจะรักษากลุ่มคำค้นหาของคุณเป็นพจนานุกรมของคู่คีย์ - ค่า
สตริงข้อความค้นหาของคุณอาจถูกกำหนดอย่างเหมาะสมมากขึ้นเป็น
?first_name={firstName}&last_name={lastName}&birth_date={birthDate}
เป็นต้น
เพื่อตอบคำถามเฉพาะของคุณ
1) การออกแบบ API ใดที่สงบมากขึ้นและทำไม ความหมายพวกมันหมายถึงและประพฤติตนในลักษณะเดียวกัน ทรัพยากรสุดท้ายใน URI คือ "children" หมายความว่าไคลเอ็นต์กำลังทำงานบนทรัพยากรชายด์อย่างมีประสิทธิภาพ
ฉันไม่คิดว่านี่จะเป็นเรื่องที่ชัดเจนอย่างที่คุณเชื่อ
ส่วนต่อประสานทรัพยากรเหล่านี้ไม่ได้สงบ ที่สำคัญที่จำเป็นสำหรับรูปแบบสถาปัตยกรรมสงบคือการประยุกต์ใช้การเปลี่ยนรัฐจะต้องมีการสื่อสารจากเซิร์ฟเวอร์เป็นสื่อสิ่งพิมพ์ ผู้คนต่างทำงานหนักกับโครงสร้างของ URIs เพื่อทำให้พวกเขา "URIs ที่สงบ" แต่วรรณกรรมที่เป็นทางการเกี่ยวกับ REST จริง ๆ แล้วมีน้อยมากที่จะพูดเกี่ยวกับเรื่องนี้ ความคิดเห็นส่วนตัวของฉันคือข้อมูลเมตาที่ผิดเกี่ยวกับ REST ส่วนใหญ่เผยแพร่โดยเจตนาทำลายนิสัยเก่าและไม่ดี (การสร้างระบบ "RESTful" อย่างแท้จริงนั้นเป็นงานค่อนข้างน้อยอุตสาหกรรมได้เข้ามาที่ "REST" และเติมความกังวลในมุมฉากบางส่วนด้วยคุณสมบัติและข้อ จำกัด ที่ไร้สาระ)
สิ่งที่วรรณกรรม REST กล่าวคือถ้าคุณจะใช้ HTTP เป็นโปรโตคอลแอปพลิเคชันของคุณคุณจะต้องปฏิบัติตามข้อกำหนดอย่างเป็นทางการของข้อกำหนดของโปรโตคอลและคุณไม่สามารถ "สร้าง http ขึ้นมาในขณะที่คุณไปและยังประกาศว่าคุณกำลังใช้ http" ; หากคุณจะใช้ URIs ในการระบุทรัพยากรของคุณคุณจะต้องปฏิบัติตามข้อกำหนดอย่างเป็นทางการของข้อกำหนดที่เกี่ยวข้องกับ URI / URL
คำถามของคุณได้รับการแก้ไขโดยตรงจาก RFC3986 §3.4ซึ่งฉันได้ทำการเชื่อมโยงไปแล้ว บรรทัดล่างของเรื่องนี้คือแม้ว่า URI ที่สอดคล้องจะไม่เพียงพอที่จะพิจารณา API "RESTful" หากคุณต้องการให้ระบบของคุณเป็น "RESTful" และคุณใช้ HTTP และ URIs คุณจะไม่สามารถระบุข้อมูลลำดับชั้นผ่าน สตริงข้อความค้นหาเนื่องจาก:
3.4 การค้นหา
องค์ประกอบแบบสอบถามประกอบด้วยข้อมูลที่ไม่เป็นลำดับชั้น
... มันง่ายอย่างนั้น
2) อะไรคือข้อดีข้อเสียของแต่ละคนในแง่ของความเข้าใจในมุมมองของลูกค้าและการบำรุงรักษาจากมุมมองของนักออกแบบ
"ข้อดี" ของสองครั้งแรกที่พวกเขาจะอยู่บนเส้นทางที่ถูกต้อง "ข้อเสีย" ของอันที่สามคือมันดูเหมือนจะผิดปกติ
เท่าที่ความเข้าใจและการบำรุงรักษาของคุณเป็นเรื่องที่แน่นอนและขึ้นอยู่กับระดับความเข้าใจของนักพัฒนาลูกค้าและการออกแบบของนักออกแบบ ข้อมูลจำเพาะ URI เป็นคำตอบที่ชัดเจนว่ารูปแบบ URI ควรถูกจัดรูปแบบอย่างไร ข้อมูลลำดับชั้นควรถูกแสดงบนพา ธ และด้วยพารามิเตอร์พา ธ ควรแสดงข้อมูลที่ไม่ใช่ลำดับชั้นในแบบสอบถาม แฟรกเมนต์มีความซับซ้อนมากขึ้นเนื่องจากความหมายของมันนั้นขึ้นอยู่กับประเภทสื่อของการเป็นตัวแทนที่ถูกร้องขอ ดังนั้นเพื่อกล่าวถึงส่วนประกอบ "ความเข้าใจ" ของคำถามของคุณฉันจะพยายามแปลสิ่งที่ URIs สองคำแรกของคุณพูด จากนั้นฉันจะพยายามแสดงสิ่งที่คุณพูดว่าคุณพยายามทำให้สำเร็จด้วย URIs ที่ถูกต้อง
การแปล URIs ที่เป็นคำต่อคำของคุณไปสู่ความหมายเชิงความหมายของพวกเขา
/myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}
สิ่งนี้พูดถึงผู้ปกครองของปู่ย่าตายายให้ค้นหาลูกของพวกเขาที่มีsearch={text}
สิ่งที่คุณพูดกับ URI ของคุณนั้นจะติดต่อกันเฉพาะเมื่อค้นหาพี่น้อง ด้วย "ปู่ย่าตายาย, ผู้ปกครอง, เด็ก ๆ " คุณพบว่า "ปู่ย่าตายาย" ขึ้นรุ่นหนึ่งไปยังพ่อแม่ของพวกเขาแล้วกลับลงมาสู่รุ่น "ปู่ย่าตายาย" โดยดูที่ลูก ๆ ของผู้ปกครอง
/myservice/api/v1/parents/{parentID}/children?search={text}
สิ่งนี้บอกว่าสำหรับผู้ปกครองที่ระบุโดย {parentID} ให้ค้นหาลูกของพวกเขาที่มี?search={text}
สิ่งนี้อยู่ใกล้เพื่อแก้ไขสิ่งที่คุณต้องการและแสดงถึงความสัมพันธ์ของผู้ปกครอง -> เด็กที่น่าจะถูกนำมาใช้เพื่อจำลอง API ทั้งหมดของคุณ ในการสร้างแบบจำลองด้วยวิธีนี้ภาระจะถูกวางไว้บนไคลเอนต์เพื่อรับรู้ว่าถ้าพวกเขามี "grandparentId" ว่ามีเลเยอร์ของการเปลี่ยนทิศทางระหว่าง ID ที่พวกเขามีและส่วนของกราฟครอบครัวที่พวกเขาต้องการเห็น หากต้องการค้นหา "child" โดย "grandparentId" คุณสามารถโทรหา/parents/{parentID}/children
บริการของคุณและจากนั้น foreach child ที่ส่งคืนแล้วค้นหาลูก ๆ ของพวกเขาเพื่อหาตัวบ่งชี้บุคคลของคุณ
การดำเนินการตามข้อกำหนดของคุณในฐานะ URIs
หากคุณต้องการสร้างแบบจำลองตัวระบุทรัพยากรที่สามารถขยายได้มากขึ้นที่สามารถเดินผ่านต้นไม้ฉันคิดได้หลายวิธีที่คุณสามารถทำได้
1)อันแรกฉันได้พาดพิงถึง แสดงกราฟของ "คน" เป็นโครงสร้างคอมโพสิต แต่ละคนมีการอ้างอิงถึงรุ่นที่อยู่เหนือเส้นทางของผู้ปกครองและรุ่นที่อยู่ด้านล่างนั้นผ่านเส้นทางลูกของตน
/Persons/Joe/Parents/Mother/Parents
จะเป็นวิธีที่จะคว้าปู่ย่าตายายของโจ
/Persons/Joe/Parents/Parents
จะเป็นวิธีที่จะคว้าปู่ย่าตายายทั้งหมดของโจ
/Persons/Joe/Parents/Parents?id={Joe.GrandparentID}
จะคว้าคุณย่าของโจโดยมีตัวระบุที่คุณมีอยู่ในมือ
และสิ่งเหล่านี้ล้วนแล้วแต่สมเหตุสมผล (โปรดทราบว่าอาจมีการลงโทษประสิทธิภาพที่นี่ขึ้นอยู่กับงานโดยบังคับให้ dfs บนเซิร์ฟเวอร์เนื่องจากไม่มีการระบุสาขาในรูปแบบ "พ่อแม่ / ผู้ปกครอง / ผู้ปกครอง") นอกจากนี้คุณยังได้รับประโยชน์จาก ความสามารถในการรองรับจำนวนรุ่นใด ๆ ถ้าด้วยเหตุผลบางอย่างคุณต้องการค้นหารุ่น 8 คุณสามารถแสดงสิ่งนี้เป็น
/Persons/Joe/Parents/Parents/Parents/Parents/Parents/Parents/Parents/Parents?id={Joe.NotableAncestor}
แต่สิ่งนี้นำไปสู่ตัวเลือกหลักที่สองสำหรับการแสดงข้อมูลนี้: ผ่านพารามิเตอร์พา ธ
2)ใช้พารามิเตอร์พา ธ เพื่อ "ค้นหาลำดับชั้น" คุณสามารถพัฒนาโครงสร้างต่อไปนี้เพื่อช่วยลดภาระของผู้บริโภคและยังมี API ที่เหมาะสม
หากต้องการมองย้อนกลับไป 147 รุ่นการแสดงตัวระบุทรัพยากรนี้พร้อมพารามิเตอร์พา ธ ช่วยให้คุณทำ
/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor}
หากต้องการค้นหา Joe จากปู่ย่าตายายที่ยิ่งใหญ่ของเขาคุณสามารถดูกราฟตามจำนวนรุ่นที่ทราบสำหรับ Joe's Id
/Persons/JoesGreatGrandparent/Children;generations=3?id={Joe.Id}
สิ่งสำคัญที่ควรทราบเมื่อใช้วิธีการเหล่านี้คือหากไม่มีข้อมูลเพิ่มเติมในตัวระบุและคำขอคุณควรคาดหวังว่า URI แรกจะดึงข้อมูลบุคคล 147 รุ่นขึ้นไปจาก Joe ด้วยตัวระบุของ Joe.NotableAncestor คุณควรคาดหวังว่าอันที่สองจะเรียกโจ สมมติว่าสิ่งที่คุณต้องการคือการที่ลูกค้าโทรของคุณสามารถดึงชุดโหนดทั้งหมดและความสัมพันธ์ระหว่างรูต Person และบริบทสุดท้ายของ URI ของคุณ คุณสามารถทำได้ด้วย URI เดียวกัน (พร้อมการตกแต่งเพิ่มเติมบางอย่าง) และการตั้งค่าการยอมรับtext/vnd.graphviz
ในคำขอของคุณซึ่งเป็นประเภทสื่อที่ลงทะเบียน IANA สำหรับการ.dot
แสดงกราฟ ด้วยการเปลี่ยน URI เป็น
/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor.Id}#directed
ด้วยส่วนหัวคำขอ HTTP
Accept: text/vnd.graphviz
และคุณสามารถให้ลูกค้าสื่อสารได้อย่างชัดเจนว่าพวกเขาต้องการกราฟกำกับของลำดับชั้นระหว่างโจและรุ่นที่ 147 ก่อนหน้านี้ที่รุ่นบรรพบุรุษรุ่นที่ 147 ประกอบด้วยบุคคลที่ถูกระบุว่าเป็น "บรรพบุรุษที่โดดเด่น" ของโจ
ฉันไม่แน่ใจว่า text / vnd.graphviz มี semantics ที่กำหนดไว้ล่วงหน้าสำหรับส่วนใด ๆ ของมันฉันไม่พบใครในการค้นหาคำแนะนำ หากประเภทสื่อนั้นจริงมีข้อมูลส่วนที่กำหนดไว้ล่วงหน้าแล้วความหมายของมันควรจะปฏิบัติตามเพื่อสร้าง URI สอดคล้อง แต่ถ้าซีแมนทิกส์เหล่านั้นไม่ได้ถูกกำหนดไว้ล่วงหน้าสเปค URI ระบุว่าซีแมนทิกส์ของตัวระบุชิ้นส่วนไม่มีข้อ จำกัด และถูกกำหนดโดยเซิร์ฟเวอร์แทนทำให้การใช้งานนี้ถูกต้อง
3) สตริงการสืบค้นที่ใช้จริงๆนอกเหนือจาก "การกรอง" ในทรัพยากรของคุณคืออะไร หากคุณใช้วิธีแรกพารามิเตอร์ตัวกรองจะถูกฝังใน URI เองเป็นพารามิเตอร์พา ธ แทนที่จะเป็นพารามิเตอร์สตริงข้อความค้นหา
ฉันเชื่อว่าฉันได้เอาชนะสิ่งนี้จนตายแล้ว แต่สตริงการสืบค้นไม่ได้สำหรับทรัพยากร "การกรอง" พวกเขามีไว้สำหรับระบุทรัพยากรของคุณจากข้อมูลที่ไม่ใช่ลำดับชั้น หากคุณเจาะลำดับชั้นของคุณด้วยเส้นทางของคุณโดยไป
/person/{id}/children/
และคุณต้องการระบุเด็กที่เฉพาะเจาะจงหรือชุดของเด็กที่เฉพาะเจาะจงคุณจะใช้คุณลักษณะบางอย่างที่ใช้กับชุดที่คุณระบุและรวมไว้ในแบบสอบถาม