So erstellen Sie eine REST-API, die ein Array von IDs für die Ressourcen verwendet

103

Ich erstelle eine REST-API für mein Projekt. Die API zum Abrufen der INFO eines bestimmten Benutzers lautet:

api.com/users/[USER-ID]

Ich möchte dem Client auch erlauben, eine Liste von Benutzer-IDs zu übergeben. Wie kann ich die API so erstellen, dass sie REST-fähig ist und eine Liste von Benutzer-IDs enthält?

uclajatt
quelle
Die allgemeinste Antwort wird von @Shuja gegeben, da andere Antworten vom Postboten nicht funktionierten und vom Datenbank-Backend abhängig sind. Sie können jedoch einen API-Endpunkt haben, um mehrere IDs anzufordern.
Eswar

Antworten:

97

Wenn Sie alle Ihre Parameter an die URL übergeben, sind wahrscheinlich durch Kommas getrennte Werte die beste Wahl. Dann hätten Sie eine URL-Vorlage wie die folgende:

api.com/users?id=id1,id2,id3,id4,id5
Florin Dumitrescu
quelle
7
@uclajatt, REST ist ein Architekturmodell und kein Protokoll. Wenn Sie die wichtigsten heute verfügbaren REST-APIs studieren, werden Sie feststellen, dass es mehrere Möglichkeiten gibt, es zu implementieren. Der von mir vorgeschlagene Ansatz ist wahrscheinlich einer der dem Konzept am nächsten kommenden, da er alle hier beschriebenen Einschränkungen erfüllt: en.wikipedia.org/wiki/… . Sie würden CSV nur zur Darstellung von Arrays in Anforderungen verwenden, während die Dienstantworten mithilfe von XML oder JSON serialisiert werden sollten. Gibt es bestimmte Gründe, warum Sie meinen Ansatz nicht als REST betrachten?
Florin Dumitrescu
10
Warum nicht das? api.com/users?id=id1&id=id2&id=id3&id=id4&id=id5
senfo
7
@senfo, ich bevorzuge id = id1, id2, id3, weil dadurch der URI kürzer und leichter zu lesen ist (von einem Menschen, zum Beispiel während eines Debugging-Vorgangs). Einzelne Parameter für jeden Wert würden es besonders schwieriger machen, dem URI zu folgen, wenn andere Parameter zwischen den IDs liegen: api.com/users?id=id1&id=id2&joined-after=2013-01-01&id=id3
Florin Dumitrescu
12
Die meisten Webserver unterstützen jedoch die URL-Länge von etwa 2.000 Byte. Wie kann ich meine API auf bis zu 5.000 IDs unterstützen?
Nicky_zs
6
@senfo In URLs wie …?id=1&id=2&id=3kann nicht garantiert werden, dass doppelte Abfrageparameter zu einem Array kombiniert werden. Mit der obigen Abfragezeichenfolge sagt PHP Ihnen, dass dies idgleich ist [1, 2, 3], aber Ruby on Rails sagt Ihnen, dass es gleich ist 3, und andere Frameworks können sich auch anders idverhalten , z 1. B. gleich . URLs wie …?id=1,2,3vermeiden dieses Verwirrungspotential.
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, obige Aufrufe sehen nicht RESTful aus, dies sind jedoch schnelle und effiziente Problemumgehungen (y). Die Länge der URL ist jedoch durch den Webserver begrenzt, z . B. Tomcat .

RESTful Versuch:

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

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

Der Server antwortet auf den URI der neu erstellten Batchtask- Ressource.

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

Jetzt kann der Client die Stapelantwort oder den Aufgabenfortschritt durch Abrufen abrufen

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


So haben andere versucht , dieses Problem zu lösen:

Nilesh
quelle
7
Die POST-Anforderung zum Abrufen mehrerer Ergebnisse ist nicht RESTful. Ihr Beispiel zeigt das Erstellen einer Ressource, wo es für POST angemessen ist, aber das ist ein völlig anderer Fall als die ursprüngliche Frage
Anentropic
2
Das Erstellen einer temporären Ressource ist RESTful, nicht wahr? Und ich bekomme Ressourcen mit GET, es ist wieder RESTful.
Nilesh
Ja, aber nichts davon war in der ursprünglichen Frage, die nur nach Informationen für mehrere Benutzer-IDs fragt
Anentropic
1
Vielen Dank an @Anentropic für den Hinweis. Ich habe die Frage noch einmal gelesen und gefragt, wie man eine REST-API erstellt, die ein Array von IDs für die Ressourcen verwendet. und ich stimme zu, meine Antwort ist anders. Entschuldigen Sie, dass Sie Ihren Standpunkt nicht verstanden haben.
Nilesh
Ich mag diese Antwort, da der RESTful-Weg, um mehrere Benutzer zu erhalten, über diesen Mechanismus erfolgt.
Shane Courtrille
20

Ich finde einen anderen Weg, dasselbe zu tun, indem ich benutze @PathParam. Hier ist das Codebeispiel.

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

Rufen Sie den Dienst unter Verwendung der folgenden URL an.

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

wo

http://localhost:8080/[War File Name]/[Servlet Mapping]/[Class Path]/data/xml/12,13,56,76
Shuja
quelle
5
Ich mag dieses, weil das GET konsistent ist. In diesem Beispiel können Sie eine oder mehrere Zahlen verwenden. Und es ist nicht wirklich eine Suche (Parameter), da Sie dem Back-End genau die IDs geben, die Sie möchten.
Markthegrea
1
Ich sehe, dass die am besten bewertete Antwort nicht funktioniert und Ihre Antwort wahrscheinlich die allgemeinste ist. Sollte als Antwort akzeptiert werden.
Eswar
18

So sehr ich diesen Ansatz bevorzuge:

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

Der richtige Weg ist

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

oder

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

So macht es das Rack . So macht es PHP . So macht es auch der Knoten ...

Kyristopher
quelle
19
Ich bin mir nicht sicher, ob es der beste Rat ist, PHP-Standards als Richtlinie zu verwenden. eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design
Trebor
So macht es Flask nicht.
Jscul
0

Sie können mit ASP.NET MVC eine Rest-API oder ein Restful-Projekt erstellen und Daten als JSON zurückgeben. Eine beispielhafte Steuerungsfunktion wäre:

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

Dann rufen Sie einfach die GetUsers-Funktion über eine reguläre AJAX-Funktion auf, die das Array von IDs bereitstellt (in diesem Fall verwende ich jQuery stringify, um das Array als Zeichenfolge zu senden und es im Controller wieder zu entmaterialisieren, aber Sie können einfach das Array von Ints senden und empfangen es als Array von Ints im Controller). Ich habe mit ASP.NET MVC eine vollständige Restful-API erstellt, die die Daten als domänenübergreifendes JSON zurückgibt und von jeder App aus verwendet werden kann. Das natürlich, wenn Sie ASP.NET MVC verwenden können.

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
quelle
3
Entschuldigung, ich habe nicht gefragt, wie die API implementiert werden soll. Ich habe nur gefragt, wie der API-URI erstellt werden soll, damit der Client auf Informationen über ein Array von Benutzern zugreifen kann. Ich kann IDs über Abfrageparameter übergeben, aber ich glaube, dass dies nicht sehr erholsam sein wird.
uclajatt
@uclajatt Warum denkst du, ist das nicht RESTful?
Darrel Miller
1
Ich glaube, dass das Übergeben von IDs oder anderen Werten über Abfrageparameter in der Tat ein erholsamer Ansatz für die Interaktion mit einem System ist. Wie du dich baust Uri liegt bei dir. Als Benutzer / alle, Benutzer / Array, Array / Benutzer oder jede andere Namenskonvention, die Sie für sinnvoll halten. In Anbetracht der Funktionsweise des MVC-Frameworks ist es sehr einfach, es zum Erstellen einer erholsamen API zu verwenden, da Sie Ihre Uris nach Bedarf organisieren und erstellen können. Sobald Sie Ihre Uris haben, können Sie Ihre Parameter mit AJAX als eine Zeichenfolge übergeben. oder als mehrere Werte, wenn Sie ein Formular verwenden und einen Beitrag zu einer MVC-Aktion verfassen.
Vasile Laur
1
@uclajatt Das ist zweimal, jetzt wurden Sie in diesem Beitrag gefragt, warum Sie der Meinung sind, dass das Übergeben einer durch Kommas getrennten Liste in einem Abfrageparameter nicht RESTful ist und Sie sich nicht einmal die Mühe machen, darauf zu antworten, geschweige denn eine dieser sehr plausiblen Lösungen zu akzeptieren! ! Nicht cool.
Samis