Cara membuat REST API yang mengambil array id untuk sumber daya

103

Saya membangun REST API untuk proyek saya. API untuk mendapatkan INFO pengguna tertentu adalah:

api.com/users/[USER-ID]

Saya juga ingin mengizinkan klien untuk memasukkan daftar ID pengguna. Bagaimana cara membangun API sehingga RESTful dan memasukkan daftar ID pengguna?

uclajatt.dll
sumber
Jawaban paling umum diberikan oleh @Shuja, karena jawaban lain dari tukang pos tidak berfungsi dan bergantung pada backend database. Namun, Anda dapat memiliki titik akhir API untuk meminta beberapa id.
Eswar

Jawaban:

97

Jika Anda meneruskan semua parameter Anda di URL, mungkin nilai yang dipisahkan koma akan menjadi pilihan terbaik. Maka Anda akan memiliki template URL seperti berikut:

api.com/users?id=id1,id2,id3,id4,id5
Florin Dumitrescu
sumber
7
@uclajatt, REST adalah model arsitektur dan bukan protokol dan jika Anda mempelajari REST API utama yang tersedia saat ini, Anda akan melihat bahwa ada banyak cara untuk mengimplementasikannya. Pendekatan yang saya sarankan mungkin salah satu yang paling dekat dengan konsep karena ia menyelesaikan semua kendala yang dijelaskan di sini: en.wikipedia.org/wiki/… . Anda hanya akan menggunakan CSV untuk merepresentasikan array dalam permintaan, sedangkan respons layanan harus diserialkan menggunakan XML atau JSON. Apakah ada alasan khusus mengapa Anda tidak menganggap pendekatan saya sebagai REST?
Florin Dumitrescu
10
Kenapa bukan ini? api.com/users?id=id1&id=id2&id=id3&id=id4&id=id5
senfo
7
@senfo, saya lebih suka id = id1, id2, id3 karena ini membuat URI lebih pendek dan lebih mudah dibaca (oleh manusia, selama operasi debugging misalnya). Parameter individual untuk setiap nilai akan membuat URI lebih sulit diikuti jika ada parameter lain di antara id: api.com/users?id=id1&id=id2&joined-after=2013-01-01&id=id3
Florin Dumitrescu
12
Namun, sebagian besar server web mendukung panjang URL sekitar 2.000 byte. Bagaimana cara membuat API saya mendukung hingga 5.000 id?
nicky_zs
6
@senfo Dalam URL seperti …?id=1&id=2&id=3, tidak ada jaminan bahwa parameter kueri duplikat akan digabungkan menjadi sebuah larik. Dengan string kueri di atas, PHP kebetulan memberi tahu Anda bahwa idsama [1, 2, 3], tetapi Ruby on Rails memberi tahu Anda bahwa itu sama 3, dan kerangka kerja lain mungkin juga bertindak berbeda, misalnya mengatakan idsama 1. URL seperti …?id=1,2,3menghindari potensi kebingungan ini.
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, panggilan di atas tidak terlihat tenang, namun ini adalah solusi cepat dan efisien (y). Tapi panjang URL dibatasi oleh webserver, misal tomcat .

Upaya tenang:

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

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

Server akan membalas URI sumber daya batchtask yang baru dibuat .

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

Sekarang klien dapat mengambil respons batch atau kemajuan tugas dengan polling

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


Beginilah upaya orang lain untuk menyelesaikan masalah ini:

Nilesh
sumber
7
Permintaan POST untuk mendapatkan banyak hasil tidak RESTful. Contoh Anda menunjukkan pembuatan sumber daya, yang sesuai untuk POST, tetapi itu kasus yang sama sekali berbeda dengan pertanyaan asli
Anentropic
2
Membuat sumber daya sementara itu tenang, bukan? Dan saya mendapatkan sumber daya menggunakan GET, lagi-lagi RESTful.
Nilesh
ya, tapi tidak ada yang ada di pertanyaan awal, yang hanya menanyakan tentang mendapatkan info untuk beberapa id pengguna
Anentropic
1
Terima kasih @Anentropic karena telah menunjukkannya. Saya membaca pertanyaan lagi yang menanyakan Bagaimana membangun REST API yang mengambil array id untuk sumber daya? dan saya setuju, jawaban saya berbeda. Maaf karena tidak mengerti maksud Anda.
Nilesh
Saya suka jawaban ini karena cara RESTful untuk mendapatkan banyak pengguna adalah melalui mekanisme ini.
Shane Courtrille
20

Saya menemukan cara lain untuk melakukan hal yang sama dengan menggunakan @PathParam. Ini contoh kodenya.

@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.
}

Panggil layanan dengan menggunakan url berikut.

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

dimana

http://localhost:8080/[War File Name]/[Servlet Mapping]/[Class Path]/data/xml/12,13,56,76
Shuja
sumber
5
Saya suka yang ini karena GETnya konsisten. Anda dapat menggunakan satu atau banyak angka dalam contoh ini. Dan ini bukan pencarian (parameter), karena Anda memberikan id bagian belakang persis yang Anda inginkan.
markthegrea
1
Saya melihat jawaban yang paling banyak disukai tidak berfungsi dan jawaban Anda mungkin yang paling umum. Harus diterima sebagai jawabannya.
Eswar
18

Sebanyak saya lebih suka pendekatan ini: -

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

Cara yang benar adalah

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

atau

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

Beginilah rak melakukannya. Beginilah cara php melakukannya. Beginilah cara node melakukannya juga ...

Kyristopher
sumber
19
Saya tidak yakin bahwa mereferensikan standar PHP sebagai pedoman untuk diikuti adalah saran terbaik. eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design
trebor
Ini bukanlah cara Flask melakukannya.
jscul
0

Anda dapat membangun Rest API atau proyek yang tenang menggunakan ASP.NET MVC dan mengembalikan data sebagai JSON. Contoh fungsi pengontrol adalah:

        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));
        }

Kemudian Anda cukup memanggil fungsi GetUsers melalui fungsi AJAX biasa yang memasok array Id (dalam hal ini saya menggunakan jQuery stringify untuk mengirim array sebagai string dan mendematerialisasikannya kembali ke pengontrol tetapi Anda cukup mengirim array int dan menerima itu sebagai array int di pengontrol). Saya telah membangun seluruh Restful API menggunakan ASP.NET MVC yang mengembalikan data sebagai json lintas domain dan dapat digunakan dari aplikasi apa pun. Itu tentunya jika Anda bisa menggunakan 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"
            });
    }
Vasile Laur
sumber
3
Maaf, saya tidak bertanya bagaimana cara mengimplementasikan API. Saya baru saja bertanya tentang cara membuat URI API sehingga klien dapat mengakses info tentang berbagai pengguna. Saya dapat mengirimkan id melalui parameter kueri, tetapi saya yakin itu tidak akan menjadi sangat tenang.
uclajatt
@uclajatt Mengapa menurut Anda itu tidak RESTful?
Darrel Miller
1
Saya percaya meneruskan id atau nilai lain melalui parameter kueri memang merupakan pendekatan yang tenang dalam berinteraksi dengan sistem. Bagaimana Anda membangun Anda Uri, itu terserah Anda. Baik itu users / all, users / array, array / users atau konvensi penamaan lainnya yang menurut Anda masuk akal. Mempertimbangkan bagaimana kerangka kerja MVC bekerja, sangat mudah menggunakannya untuk membangun API yang tenang karena Anda dapat mengatur dan membangun Uris seperti yang Anda butuhkan. Setelah Anda memiliki Uris, Anda dapat mengirimkan parameter menggunakan AJAX sebagai satu string, atau sebagai beberapa nilai jika Anda menggunakan formulir dan melakukan posting ke tindakan MVC.
Vasile Laur
1
@uclajatt Itu dua kali sekarang Anda telah ditanyai di posting ini mengapa menurut Anda melewatkan daftar yang dipisahkan koma dalam parameter kueri tidak tenang dan Anda bahkan tidak repot-repot menjawabnya, apalagi menerima solusi yang sangat masuk akal ini!? ! Tidak keren.
samis