วิธีสร้าง REST API ที่ใช้อาร์เรย์ของ id สำหรับทรัพยากร


103

ฉันกำลังสร้าง REST API สำหรับโครงการของฉัน API สำหรับการรับ INFO ของผู้ใช้คือ:

api.com/users/[USER-ID]

ฉันต้องการอนุญาตให้ลูกค้าส่งผ่านรายการ ID ผู้ใช้ ฉันจะสร้าง API เพื่อให้ RESTful และอยู่ในรายการ ID ผู้ใช้ได้อย่างไร


คำตอบทั่วไปส่วนใหญ่ได้รับจาก @Shuja ทำให้คำตอบอื่น ๆ จากบุรุษไปรษณีย์ไม่ได้ผลและขึ้นอยู่กับแบ็กเอนด์ของฐานข้อมูล อย่างไรก็ตามคุณสามารถมีจุดสิ้นสุดของ API เพื่อขอรหัสหลายตัวได้
Eswar

คำตอบ:


98

หากคุณกำลังส่งพารามิเตอร์ทั้งหมดของคุณไปยัง URL ค่าที่คั่นด้วยลูกน้ำอาจเป็นตัวเลือกที่ดีที่สุด จากนั้นคุณจะมีเทมเพลต URL ดังต่อไปนี้:

api.com/users?id=id1,id2,id3,id4,id5

7
@uclajatt, REST เป็นโมเดลสถาปัตยกรรมไม่ใช่โปรโตคอลและหากคุณศึกษา REST API หลัก ๆ ที่มีอยู่ในปัจจุบันคุณจะเห็นว่ามีหลายวิธีในการนำไปใช้ วิธีการที่ผมบอกอาจเป็นหนึ่งในที่ใกล้เคียงกับแนวความคิดเพราะมันสำเร็จข้อ จำกัด ทั้งหมดที่อธิบายที่นี่: en.wikipedia.org/wiki/... คุณจะใช้ CSV เพื่อแสดงอาร์เรย์ในคำขอเท่านั้นในขณะที่การตอบกลับของบริการควรเป็นอนุกรมโดยใช้ XML หรือ JSON มีเหตุผลพิเศษใดบ้างที่คุณไม่คิดว่าแนวทางของฉันเป็น REST?
Florin Dumitrescu

10
ทำไมไม่เป็นเช่นนี้? api.com/users?id=id1&id=id2&id=id3&id=id4&id=id5
senfo

7
@senfo ฉันชอบ id = id1, id2, id3 เพราะทำให้ URI สั้นลงและอ่านง่ายขึ้น (โดยมนุษย์ในระหว่างการดำเนินการดีบักเป็นต้น) พารามิเตอร์แต่ละตัวสำหรับแต่ละค่าจะทำให้ URI ติดตามยากขึ้นเป็นพิเศษหากมีพารามิเตอร์อื่น ๆ ระหว่าง ids: api.com/users?id=id1&id=id2&joined-after=2013-01-01&id=id3
Florin Dumitrescu

12
อย่างไรก็ตามเว็บเซิร์ฟเวอร์ส่วนใหญ่รองรับความยาว URL ประมาณ 2,000 ไบต์ จะทำให้ API ของฉันรองรับ 5,000 ID ได้อย่างไร
nicky_zs

6
@senfo ใน URL ที่ชอบ…?id=1&id=2&id=3, มีการรับประกันไม่ว่าพารามิเตอร์การค้นหาที่ซ้ำกันจะถูกรวมเป็นอาร์เรย์ ด้วยสตริงแบบสอบถามดังกล่าวข้างต้น, PHP เกิดขึ้นจะบอกคุณว่าidเท่ากับ[1, 2, 3]แต่ Ruby on Rails จะบอกคุณว่ามันเท่ากับ3และกรอบอื่น ๆ นอกจากนี้ยังอาจทำหน้าที่แตกต่างกันเช่นบอกว่าเท่ากับid 1URL เช่น…?id=1,2,3หลีกเลี่ยงปัญหานี้ที่อาจเกิดความสับสน
Rory O'Kane

33
 api.com/users?id=id1,id2,id3,id4,id5
 api.com/users?ids[]=id1&ids[]=id2&ids[]=id3&ids[]=id4&ids[]=id5

IMO การโทรข้างต้นดูไม่น่าสนใจ แต่เป็นการแก้ปัญหาที่รวดเร็วและมีประสิทธิภาพ (y) แต่ความยาวของ URL จะถูก จำกัด โดยเว็บเซิร์ฟเวอร์เช่นคราว

ความพยายามอย่างสงบ:

POST http://example.com/api/batchtask

   [
    {
      method : "GET",
      headers : [..],
      url : "/users/id1"
    },
    {
      method : "GET",
      headers : [..],
      url : "/users/id2"
    }
   ]

เซิร์ฟเวอร์จะตอบกลับ URI ของทรัพยากรชุดงานที่สร้างขึ้นใหม่

201 Created
Location: "http://example.com/api/batchtask/1254"

ตอนนี้ไคลเอนต์สามารถดึงการตอบสนองแบบแบตช์หรือความคืบหน้าของงานโดยการสำรวจ

GET http://example.com/api/batchtask/1254


นี่คือวิธีที่คนอื่นพยายามแก้ไขปัญหานี้:


7
คำขอ POST เพื่อให้ได้ผลลัพธ์หลายรายการไม่ใช่ RESTful ตัวอย่างของคุณแสดงการสร้างทรัพยากรในตำแหน่งที่เหมาะสมสำหรับการโพสต์ แต่เป็นกรณีที่แตกต่างกันโดยสิ้นเชิงกับคำถามเดิม
Anentropic

2
การสร้างทรัพยากรชั่วคราวเป็นสิ่งที่น่าสนใจใช่หรือไม่ และฉันได้รับทรัพยากรโดยใช้ GET ซึ่งเป็น RESTful อีกครั้ง
Nilesh

ใช่ แต่ไม่ได้อยู่ในคำถามเดิมซึ่งเพิ่งถามเกี่ยวกับการรับข้อมูลสำหรับรหัสผู้ใช้หลายรายการ
Anentropic

1
ขอบคุณ @Anentropic ที่ชี้ให้เห็น ฉันอ่านคำถามอีกครั้งถามว่าจะสร้าง REST API ที่ใช้อาร์เรย์ของ id สำหรับทรัพยากรได้อย่างไร และฉันยอมรับคำตอบของฉันแตกต่างกัน ขออภัยที่ไม่เข้าใจประเด็นของคุณ
Nilesh

ฉันชอบคำตอบนี้เนื่องจากเป็นวิธีที่ดีในการรับผู้ใช้หลายคนผ่านกลไกนี้
Shane Courtrille

20

@PathParamผมพบว่าวิธีการทำในสิ่งเดียวกันโดยใช้อีก นี่คือตัวอย่างโค้ด

@GET
@Path("data/xml/{Ids}")
@Produces("application/xml")
public Object getData(@PathParam("zrssIds") String Ids)
{
  System.out.println("zrssIds = " + Ids);
  //Here you need to use String tokenizer to make the array from the string.
}

เรียกใช้บริการโดยใช้ url ต่อไปนี้

http://localhost:8080/MyServices/resources/cm/data/xml/12,13,56,76

ที่ไหน

http://localhost:8080/[War File Name]/[Servlet Mapping]/[Class Path]/data/xml/12,13,56,76

5
ฉันชอบอันนี้เพราะ GET มีความสม่ำเสมอ คุณสามารถใช้ตัวเลขหนึ่งหรือหลายตัวในตัวอย่างนี้ และมันไม่ใช่การค้นหา (พารามิเตอร์) จริงๆเนื่องจากคุณให้รหัสส่วนหลังที่คุณต้องการ
markthegrea

1
ฉันเห็นว่าคำตอบที่ได้รับการโหวตมากที่สุดใช้ไม่ได้ผลและคำตอบของคุณน่าจะเป็นคำตอบทั่วไปที่สุด ควรรับเป็นคำตอบ.
Eswar

18

ฉันชอบแนวทางนี้มากที่สุด: -

    api.com/users?id=id1,id2,id3,id4,id5

วิธีที่ถูกต้องคือ

    api.com/users?ids[]=id1&ids[]=id2&ids[]=id3&ids[]=id4&ids[]=id5

หรือ

    api.com/users?ids=id1&ids=id2&ids=id3&ids=id4&ids=id5

นี่คือวิธีที่แร็คทำ นี่คือวิธีที่phpทำ นี่คือวิธีที่โหนดทำเช่นกัน ...


19
ฉันไม่แน่ใจว่าการอ้างอิงมาตรฐาน PHP เพื่อเป็นแนวทางปฏิบัติตามเป็นคำแนะนำที่ดีที่สุด eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design
trebor

นี่ไม่ใช่วิธีที่ Flask ทำ
jscul

0

คุณสามารถสร้าง Rest API หรือโครงการพักผ่อนโดยใช้ ASP.NET MVC และส่งคืนข้อมูลเป็น JSON ตัวอย่างฟังก์ชันคอนโทรลเลอร์จะเป็น:

        public JsonpResult GetUsers(string userIds)
        {
           var values = JsonConvert.DeserializeObject<List<int>>(userIds);

            var users = _userRepository.GetAllUsersByIds(userIds);

            var collection = users.Select(user => new { id = user.Id, fullname = user.FirstName +" "+ user.LastName });
            var result = new { users = collection };

            return this.Jsonp(result);
        }
        public IQueryable<User> GetAllUsersByIds(List<int> ids)
        {
            return _db.Users.Where(c=> ids.Contains(c.Id));
        }

จากนั้นคุณก็เรียกใช้ฟังก์ชัน GetUsers ผ่านฟังก์ชั่น AJAX ปกติที่จัดหาอาร์เรย์ของ Ids (ในกรณีนี้ฉันใช้ jQuery stringify เพื่อส่งอาร์เรย์เป็นสตริงและลดขนาดวัสดุกลับในคอนโทรลเลอร์ แต่คุณสามารถส่งอาร์เรย์ของ ints และรับได้ เป็นอาร์เรย์ของ int ในคอนโทรลเลอร์) ฉันสร้าง Restful API ทั้งหมดโดยใช้ ASP.NET MVC ที่ส่งคืนข้อมูลเป็น json ข้ามโดเมนและสามารถใช้จากแอปใดก็ได้ แน่นอนว่าถ้าคุณสามารถใช้ ASP.NET MVC

function GetUsers()
    {
           var link = '<%= ResolveUrl("~")%>users?callback=?';
           var userIds = [];
            $('#multiselect :selected').each(function (i, selected) {
                userIds[i] = $(selected).val();
            });

            $.ajax({
                url: link,
                traditional: true,
                data: { 'userIds': JSON.stringify(userIds) },
                dataType: "jsonp",
                jsonpCallback: "refreshUsers"
            });
    }

3
ขออภัยฉันไม่ได้ขอวิธีใช้ API ฉันแค่ถามถึงวิธีสร้าง API URI เพื่อให้ไคลเอนต์สามารถเข้าถึงข้อมูลเกี่ยวกับกลุ่มผู้ใช้ ฉันสามารถส่งรหัสผ่านพารามิเตอร์การค้นหาได้ แต่ฉันเชื่อว่าจะไม่ 'นิ่งนอนใจมาก
uclajatt

@uclajatt ทำไมคุณถึงคิดว่ามันไม่น่าสนใจ?
Darrel Miller

1
ฉันเชื่อว่าการส่งรหัสหรือค่าอื่น ๆ ผ่านพารามิเตอร์การค้นหาเป็นวิธีการโต้ตอบกับระบบอย่างสงบ คุณสร้าง Uri อย่างไรขึ้นอยู่กับคุณ ไม่ว่าจะเป็นผู้ใช้ / ทั้งหมดผู้ใช้ / อาร์เรย์อาร์เรย์ / ผู้ใช้หรือรูปแบบการตั้งชื่ออื่น ๆ ที่คุณรู้สึกว่าเหมาะสม พิจารณาว่าเฟรมเวิร์ก MVC ทำงานอย่างไรมันง่ายมากที่จะใช้สำหรับการสร้าง API ที่สงบเนื่องจากคุณสามารถจัดระเบียบและสร้าง Uris ของคุณได้ตามที่คุณต้องการเมื่อคุณมี Uris ของคุณแล้วคุณสามารถส่งผ่านพารามิเตอร์ของคุณโดยใช้ AJAX เป็นสตริงเดียว หรือเป็นค่าหลายค่าหากคุณกำลังใช้แบบฟอร์มและโพสต์ไปยังการกระทำ MVC
Vasile Laur

1
@uclajatt นั่นคือสองครั้งที่คุณถูกถามในโพสต์นี้ว่าทำไมคุณถึงคิดว่าการส่งรายการที่คั่นด้วยเครื่องหมายจุลภาคในพารามิเตอร์การค้นหานั้นไม่น่าสนใจและคุณไม่ต้องกังวลที่จะตอบเลยนับประสาอะไรกับวิธีแก้ปัญหาที่เป็นไปได้เหล่านี้!? ! ไม่เท่.
samis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.