REST API สามารถส่งคืนทรัพยากรจำนวนมากเป็นทรัพยากรทรัพยากรเดียวได้หรือไม่


10

ฉันอยู่ระหว่างดำเนินการสร้าง REST API และขณะนี้ฉันกำลังประสบปัญหาดังต่อไปนี้:

  • Fooเป็นทรัพยากรแรก การดำเนินการ CRUD สามารถนำไปใช้ผ่าน/foo/URI
  • Barเป็นทรัพยากรที่สอง การดำเนินการ CRUD สามารถนำไปใช้ผ่าน/bar/URI
  • ทุกคนมีความเกี่ยวข้องกับศูนย์หรือหนึ่งFoo Barเหตุผลที่ฉันไม่ถือว่าBarเป็นแหล่งข้อมูลย่อยของFooคือเนื่องจากBarอินสแตนซ์เดียวกันสามารถใช้ร่วมกันระหว่าง mutiple Foos ดังนั้นผมจึงคิดว่ามันจะดีกว่าที่จะเข้าถึงได้ผ่านทางเป็นอิสระ URI /foo/[id]/barแทน

ปัญหาของฉันคือในกรณีจำนวนมากลูกค้าที่ขอFooอินสแตนซ์ก็สนใจBarอินสแตนซ์ที่เกี่ยวข้องเช่นกัน ขณะนี้หมายความว่าพวกเขาจะต้องดำเนินการสองแบบสอบถามแทนหนึ่งแบบสอบถาม ฉันต้องการแนะนำวิธีที่ช่วยให้รับวัตถุทั้งสองด้วยการสืบค้นเพียงครั้งเดียว แต่ฉันไม่รู้วิธีจำลอง API สำหรับการทำ สิ่งที่ฉันมาด้วย:

  • ฉันสามารถแนะนำพารามิเตอร์การสืบค้นที่คล้ายกับสิ่งนี้: /foo/[id]?include_bar=true. ปัญหาด้วยวิธีการนี้คือการเป็นตัวแทนทรัพยากร (เช่นโครงสร้าง JSON) ของการตอบสนองจะต้องดูแตกต่างกัน (เช่นภาชนะเช่น{ foo: ..., bar: ... }แทนที่จะเป็นแบบอนุกรมFoo) ซึ่งทำให้Fooจุดสิ้นสุดของทรัพยากร "แตกต่าง" ฉันไม่คิดว่ามันเป็นสิ่งที่ดี เมื่อทำการสอบถาม/fooลูกค้าควรได้รับการแสดงทรัพยากรเดียวกัน (โครงสร้าง) เสมอโดยไม่คำนึงถึงพารามิเตอร์การสืบค้น
  • /fooandbar/[foo-id]ความคิดก็คือการแนะนำปลายทางอ่านอย่างเดียวใหม่เช่น ในกรณีนี้จะไม่มีปัญหาในการส่งคืนการแสดงแทนเช่น{ foo: ..., bar: ... }นั้นเพราะมันเป็นเพียงการแสดง "อย่างเป็นทางการ" ของfooandbarทรัพยากร อย่างไรก็ตามฉันไม่รู้ว่าจุดสิ้นสุดของผู้ช่วยเหลือนั้นสงบหรือไม่ (นี่คือสาเหตุที่ฉันเขียน "สามารถ" ในชื่อคำถามได้แน่นอนว่าเป็นไปได้ทางเทคนิค แต่ฉันไม่รู้ว่าเป็นความคิดที่ดีหรือไม่)

คุณคิดอย่างไร? มีความเป็นไปได้อื่น ๆ อีกไหม?


อะไรคือความสัมพันธ์ระหว่างฟูกับบาร์? คุณบอกได้ไหมว่าบาร์เป็นพ่อแม่ของฟู?
Nathan Merrill

ไม่สามารถอยู่ได้โดยไม่ต้องเชื่อมโยงกับBar Fooอย่างไรก็ตามในขณะที่ผมเขียนข้างต้นก็เป็นไปได้ว่าหลายFoos Barแบ่งปันเดียวกัน มันควรจะเป็นไปได้ในการสร้างFooไม่มีโดยไม่Barเกี่ยวข้องดังนั้นฉันไม่คิดว่าBarควรได้รับการปฏิบัติในฐานะผู้ปกครอง
ceran

1
ฉันคิดว่าคุณกำลังประสบปัญหาบางอย่างที่ฉันมีโดยการแปลโดยตรงความสัมพันธ์รูปแบบโดเมนลงใน URL และเท่าทรัพยากรเพื่อหน่วยงานโดเมน มันอาจจะสนใจREST API ที่จะต้องเป็นไฮเปอร์ขับเคลื่อน ให้ความสนใจเป็นพิเศษกับประเด็นที่ 4
Laiv

คำตอบ:


6

ระดับ 3 REST API จะกลับคุณและยังมีการเชื่อมโยงชี้ไปที่เกี่ยวข้องFooBar

GET /foo/123
<foo id="123">
  ..foo stuff..
  <link rel="bar" uri="/bar/456"/>
</foo>

จากนั้นคุณสามารถเพิ่มฟีเจอร์ "เจาะลึก" ลงใน API ของคุณซึ่งอนุญาตการนำทางของลิงก์

GET /foo/123?drilldown=bar
<foo id="123">
  ..foo stuff..
  <link rel="bar" uri="/bar/456">
    <bar id="456">
      ..bar stuff...
    </bar>
  </link>
</foo>

คุณลักษณะการดริลดาวน์จะอยู่ตรงหน้า API และตัดการตอบสนอง มันจะทำการเจาะลึกการโทรและกรอกรายละเอียดก่อนส่งคำตอบกลับไปยังผู้โทร

นี่เป็นสิ่งที่พบได้บ่อยในระดับ 3 REST เนื่องจากจะช่วยลดความไม่แน่นอนของลูกค้า / เซิร์ฟเวอร์ผ่าน http ช้า บริษัท ที่ฉันทำงานเพื่อผลิต API REST ระดับ 3 ด้วยคุณสมบัตินี้

อัปเดต: สิ่งที่มีค่าควรดูที่ JSON นี่คือวิธีที่ API ของเราจะจัดโครงสร้าง โปรดทราบว่าคุณสามารถวางซ้อนดาวน์เพื่อดึงลิงก์ของลิงก์ ฯลฯ

GET /foo/123?drilldown=bar

{
  "self": {
    "type": "thing.foo",
    "uri": "/foo/123=?drilldown=bar",
    "href": "http://localhost/api/foo/123?drilldown=bar"
  },
  "links": [
    {
      "rel": "bar",
      "rev": "foo",
      "type": "thing.bar",
      "uri": "/bar/456",
      "href": "http://localhost/api/bar/456"
    }
  ],
  "_bar": [
    {
      "self": {
        "type": "thing.bar",
        "uri": "/bar/456",
        "href": "http://localhost/api/bar/456"
      },
      "links": [
        {
          ..other link..
        },
        {
          ..other link..
        }
      ]
    }
  ]
}

น่าสนใจฉันกำลังใช้ลิงค์ / ตัวควบคุมไฮเปอร์มีเดียอยู่แล้วเพื่อลบข้อ จำกัด ที่แน่นไปสู่ ​​URIs แต่ฉันไม่ได้คิดเกี่ยวกับแนวคิด "เจาะลึก" ซึ่งดูเหมือนว่าจะมีแนวโน้มมาก การแสดง JSON เป็นอย่างไรในขณะนี้การแสดง JSON ของทรัพยากรของฉันlinksแต่ละอันมีอาเรย์แต่ละรายการเป็นวัตถุลิงค์ที่มีrelและuriฟิลด์ (คล้ายกับตัวอย่าง xml ของคุณ) ฉันควรเพิ่มเขตข้อมูลที่สามในแต่ละวัตถุลิงก์ (เช่นdata) หรือไม่ มีมาตรฐานหรือไม่?
ceran

การเจาะลึกไม่ใช่คุณลักษณะที่เหลือจริงๆดังนั้นจึงไม่มีมาตรฐาน (อย่างน้อยฉันก็รู้)
Qwerky

มีมาตรฐานที่เสนอเช่นstateless.co/hal_specification.htmlซึ่งฉันใช้ในแอปพลิเคชันของเรา มันใกล้เคียงกับตัวอย่างของคุณมาก
Pete Kirkham

4

ถ้า 95% ของแบบสอบถามทั้งหมดต้องการFooเช่นเดียวBarแล้วก็ส่งกลับมาภายในของFooวัตถุFooเมื่อคุณขอ เพียงเพิ่มคุณสมบัติbar(หรือคำอื่น ๆ สำหรับความสัมพันธ์) และวางBarวัตถุไว้ที่นั่น หากความสัมพันธ์ไม่มีอยู่ให้ใช้ค่า null

ฉันคิดว่าคุณคิดมากเรื่องนี้ :)


ฉันไม่ควรคิดเลขนั้น (95%) มันเป็นความผิดพลาดขอโทษ สิ่งที่ฉันต้องการจะพูดคือคำขอส่วนใหญ่สนใจทั้งสองทรัพยากรในเวลาเดียวกัน แต่ยังมีจำนวนคำขอที่เกี่ยวข้องที่สนใจเพียงอย่างเดียวFooและเนื่องจากแต่ละBarหน่วยความจำมีขนาดใหญ่มาก (ประมาณขนาด 3x-4x Foo) ฉันไม่ต้องการส่งคืนBarถ้าไคลเอ็นต์ไม่ร้องขออย่างชัดเจน
ceran

เราคุยกันใหญ่แค่ไหน ผมสงสัยว่ามันจะทำให้ที่แตกต่างกันมากในเวลาการโอนและฉันชอบ API สะอาดความเร็ว
นาธานเมอร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.