Wann wird @QueryParam vs @PathParam verwendet?

276

Ich stelle nicht die Frage, die hier bereits gestellt wird: Was ist der Unterschied zwischen @PathParam und @QueryParam

Dies ist eine "Best Practices" - oder Konventionsfrage.

Wann würden Sie @PathParamvs verwenden @QueryParam.

Was ich mir vorstellen kann, könnte die Entscheidung darin bestehen, die beiden zur Unterscheidung des Informationsmusters zu verwenden. Lassen Sie mich unten mein LTPO veranschaulichen - weniger als perfekte Beobachtung.

Die Verwendung von PathParam könnte für die Informationskategorie reserviert werden, die gut in einen Zweig eines Informationsbaums passt. PathParam kann verwendet werden, um einen Drilldown zur Entitätsklassenhierarchie durchzuführen.

QueryParam könnte für die Angabe von Attributen zum Auffinden der Instanz einer Klasse reserviert werden.

Zum Beispiel,

  • /Vehicle/Car?registration=123
  • /House/Colonial?region=newengland

/category?instance

@GET
@Path("/employee/{dept}")
Patient getEmployee(@PathParam("dept")Long dept, @QueryParam("id")Long id) ;

vs. /category/instance

@GET
@Path("/employee/{dept}/{id}")
Patient getEmployee(@PathParam("dept")Long dept, @PathParam("id")Long id) ;

vs. ?category+instance

@GET
@Path("/employee")
Patient getEmployee(@QueryParam("dept")Long dept, @QueryParam("id")Long id) ;

Ich glaube nicht, dass es eine Standardkonvention dafür gibt. Gibt es? Ich würde jedoch gerne hören, wie Leute PathParam vs QueryParam verwenden, um ihre Informationen zu differenzieren, wie ich es oben veranschaulicht habe. Ich würde auch gerne den Grund für die Praxis hören.

Gesegneter Geek
quelle
4
Mögliches Duplikat von Wann PathParams oder QueryParams verwendet werden sollen
Joachim Sauer

Antworten:

245

REST ist möglicherweise kein Standard als solcher, aber das Lesen der allgemeinen REST-Dokumentation und der Blog-Beiträge sollte Ihnen einige Richtlinien für eine gute Möglichkeit zum Strukturieren von API-URLs geben. Die meisten Rest-APIs enthalten normalerweise nur Ressourcennamen und Ressourcen-IDs im Pfad. Sowie:

/departments/{dept}/employees/{id}

Einige REST-APIs verwenden Abfragezeichenfolgen zum Filtern, Paginieren und Sortieren. Da REST jedoch kein strenger Standard ist, würde ich empfehlen, einige REST-APIs wie Github und Stackoverflow zu überprüfen und festzustellen, was für Ihren Anwendungsfall gut funktionieren könnte.

Ich würde empfehlen, alle erforderlichen Parameter in den Pfad einzufügen, und alle optionalen Parameter sollten auf jeden Fall Abfragezeichenfolgenparameter sein. Das Einfügen optionaler Parameter in den Pfad wird beim Versuch, URL-Handler zu schreiben, die verschiedenen Kombinationen entsprechen, sehr unübersichtlich.

die auf
quelle
73
" Ich würde empfehlen, alle erforderlichen Parameter in den Pfad
einzufügen
1
Sollte diese Konvention auch für Put-Anfragen verwendet werden, sagen wir, wir möchten eine bestimmte Version der DB-Entität aktualisieren, sollte der URI PUT /depatments/{dept}/employees/{id}/{version}und die Version optional sein oder sollte es sein PUT /depatments/{dept}/employees/{id}?version=12und sollte die Version optional sein
besten Wünsche
In diesem Fall würde ich empfehlen: - PUT /depatments/{dept}/employees/{id}/versions/{version}einen Mitarbeiter mit einer ausgewählten Version POST /depatments/{dept}/employees/{id}/versionszu erstellen - einen Mitarbeiter mit einer vom Backend festgelegten Version zu erstellen
Guillaume Vauvert
90

Das ist was ich mache.

Wenn es ein Szenario gibt, in dem ein Datensatz basierend auf der ID abgerufen werden kann, z. B. wenn Sie die Details des Mitarbeiters mit der ID 15 abrufen müssen, können Sie über Ressourcen mit @PathParam verfügen.

GET /employee/{id}

Wenn es ein Szenario gibt, in dem Sie die Details aller Mitarbeiter abrufen müssen, jedoch jeweils nur 10, können Sie den Abfrageparameter verwenden

GET /employee?start=1&size=10

Dies besagt, dass das Starten von Mitarbeiter-ID 1 zehn Datensätze erhält.

Verwenden Sie zusammenfassend @PathParam zum Abrufen basierend auf der ID. Benutzer @QueryParam für Filter oder wenn Sie eine feste Liste von Optionen haben, die Benutzer übergeben können.

Arun B Chandrasekaran
quelle
Bieten sowohl '@PathParam' als auch '@QueryParam' die gleiche Funktionalität? Ist '@QueryParam' nur eine andere Art, dasselbe zu schreiben?
Rishabh Agarwal
1
@RishabhAgarwal Obwohl beide die gleiche Funktionalität bieten, wird empfohlen, einen erforderlichen Parameter als Pfadvariable und einen optionalen Parameter als Abfrageparameter zu verwenden.
Akhil Ghatiki
@RishabhAgarwal Weitere Informationen finden Sie in meinem Artikel Best API Best Practices
Arun B Chandrasekaran
43

Ich denke, wenn der Parameter eine bestimmte Entität identifiziert, sollten Sie eine Pfadvariable verwenden. Um beispielsweise alle Beiträge in meinem Blog zu erhalten, fordere ich an

GET: myserver.com/myblog/posts

Um den Beitrag mit id = 123 zu erhalten, würde ich darum bitten

GET: myserver.com/myblog/posts/123

Aber um meine Liste der Beiträge zu filtern und alle Beiträge seit dem 1. Januar 2013 zu erhalten, würde ich darum bitten

GET: myserver.com/myblog/posts?since=2013-01-01

Im ersten Beispiel identifiziert "posts" eine bestimmte Entität (die gesamte Sammlung von Blog-Posts). Im zweiten Beispiel repräsentiert "123" auch eine bestimmte Entität (einen einzelnen Blog-Beitrag). Im letzten Beispiel ist der Parameter "seit = 2013-01-01" eine Anforderung zum Filtern der Postsammlung, nicht einer bestimmten Entität. Paginierung und Bestellung wären ein weiteres gutes Beispiel, dh

GET: myserver.com/myblog/posts?page=2&order=backward

Hoffentlich hilft das. :-)

10GritSandpaper
quelle
8

Ich persönlich habe den Ansatz verwendet: "Wenn es für den Benutzer sinnvoll ist, eine URL mit einem Lesezeichen zu versehen, die diese Parameter enthält, verwenden Sie PathParam."

Wenn die URL für ein Benutzerprofil beispielsweise einen Profil-ID-Parameter enthält, da dieser vom Benutzer mit einem Lesezeichen versehen und / oder per E-Mail versendet werden kann, würde ich diese Profil-ID als Pfadparameter einschließen. Ein weiterer Aspekt ist, dass sich die Seite, die durch die URL mit dem Pfadparameter gekennzeichnet ist, nicht ändert. Der Benutzer richtet sein Profil ein, speichert es und wird sich von da an wahrscheinlich nicht mehr so ​​stark ändern. Dies bedeutet, dass Webcrawler / Suchmaschinen / Browser / usw. diese Seite basierend auf dem Pfad gut zwischenspeichern können.

Wenn ein in der URL übergebener Parameter wahrscheinlich das Seitenlayout / den Seiteninhalt ändert, würde ich dies als Queryparam verwenden. Wenn die Profil-URL beispielsweise einen Parameter unterstützt, der angibt, ob die Benutzer-E-Mail angezeigt werden soll oder nicht, würde ich dies als Abfrageparameter betrachten. (Ich weiß, man könnte wohl sagen, dass der &noemail=1oder welcher Parameter auch immer als Pfadparameter verwendet werden kann und zwei separate Seiten generiert - eine mit der E-Mail darauf, eine ohne - aber logischerweise ist das nicht der Fall: es wird immer noch dieselbe Seite mit oder ohne bestimmte Attribute angezeigt.

Hoffe das hilft - ich schätze die Erklärung könnte etwas verschwommen sein :)

Liv
quelle
Ich denke, diese Antworten verwechseln Ressourcen mit Routen. Die Frage bezieht sich auf die Ressourcen einer REST-API, die normalerweise JSON oder XML zurückgibt, und nicht auf die Routen einer Webanwendung, mit denen Sie innerhalb der Anwendung navigieren können.
Hampus
5

Das ist eine sehr interessante Frage.

Sie können beide verwenden, es gibt keine strengen Regeln zu diesem Thema, aber die Verwendung von URI-Pfadvariablen hat einige Vorteile:

  • Cache : Die meisten Web-Cache-Dienste im Internet speichern GET-Anforderungen nicht zwischen, wenn sie Abfrageparameter enthalten. Sie tun dies, weil es viele RPC-Systeme gibt, die GET-Anforderungen verwenden, um Daten auf dem Server zu ändern (fehlgeschlagen !! Get muss eine sichere Methode sein).

Wenn Sie jedoch Pfadvariablen verwenden, können alle diese Dienste Ihre GET-Anforderungen zwischenspeichern.

  • Hierarchie : Die Pfadvariablen können die Hierarchie darstellen: / Stadt / Straße / Ort

Es gibt dem Benutzer mehr Informationen über die Struktur der Daten.

Wenn Ihre Daten jedoch keine Hierarchiebeziehung haben, können Sie weiterhin Pfadvariablen mit Komma oder Semikolon verwenden:

/ Stadt / Längengrad, Breitengrad

Verwenden Sie in der Regel Komma, wenn die Reihenfolge der Parameter wichtig ist, und Semikolon, wenn die Reihenfolge keine Rolle spielt:

/ IconGenerator / rot; blau; grün

Abgesehen von diesen Gründen gibt es einige Fälle, in denen häufig Abfragezeichenfolgenvariablen verwendet werden:

  • Wenn der Browser automatisch HTML-Formularvariablen in den URI einfügen muss
  • Wenn Sie mit Algorithmus zu tun haben. Beispielsweise verwendet die Google Engine Abfragezeichenfolgen:

http: // www.google.com/search?q=rest

Zusammenfassend lässt sich sagen, dass es keinen triftigen Grund gibt, eine dieser Methoden zu verwenden, aber wann immer Sie können, verwenden Sie URI-Variablen.

jfcorugedo
quelle
2

Wie bereits erwähnt, ist REST kein Standard. Wenn Sie jedoch eine standardbasierte URI-Konvention implementieren möchten , können Sie die oData-URI-Konvention in Betracht ziehen . Ver 4 wurde als OASIS-Standard genehmigt und es gibt Bibliotheken für oData für verschiedene Sprachen, einschließlich Java über Apache Olingo . Lassen Sie sich nicht von der Tatsache abschrecken, dass es sich um einen Spawn von Microsoft handelt, da er auch von anderen Branchenakteuren unterstützt wird , darunter Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook und SAP

Weitere Anwender sind hier aufgelistet

MikeM
quelle
2

Aus Wikipedia: Uniform Resource Locator

Ein Pfad , der Daten enthält, die normalerweise in hierarchischer Form organisiert sind und als Folge von Segmenten angezeigt werden, die durch Schrägstriche getrennt sind.

Eine optionale Abfrage , die durch ein Fragezeichen (?) Vom vorhergehenden Teil getrennt ist und eine Abfragezeichenfolge nicht hierarchischer Daten enthält .

- Entsprechend dem konzeptionellen Design der URL implementieren wir möglicherweise ein PathParam für hierarchische Daten / Anweisungen / Locator-Komponenten oder ein QueryParam, wenn die Daten nicht hierarchisch sind. Dies ist sinnvoll, da Pfade natürlich geordnet sind, während Abfragen Variablen enthalten, die beliebig geordnet werden können (ungeordnete Variablen / Wert-Paare).

Ein vorheriger Kommentator schrieb:

Ich denke, wenn der Parameter eine bestimmte Entität identifiziert, sollten Sie eine Pfadvariable verwenden.

Ein anderer schrieb:

Verwenden Sie @PathParam zum Abrufen basierend auf der ID. Benutzer @QueryParam für Filter oder wenn Sie eine feste Liste von Optionen haben, die Benutzer übergeben können.

Ein weiterer,

Ich würde empfehlen, alle erforderlichen Parameter in den Pfad einzufügen, und alle optionalen Parameter sollten auf jeden Fall Abfragezeichenfolgenparameter sein.

- Man könnte jedoch ein flexibles, nicht hierarchisches System zur Identifizierung bestimmter Entitäten implementieren! Eine SQL-Tabelle verfügt möglicherweise über mehrere eindeutige Indizes und ermöglicht die Identifizierung von Entitäten mithilfe einer beliebigen Kombination von Feldern, die einen eindeutigen Index enthalten. Verschiedene Kombinationen (möglicherweise auch anders geordnet) können für Links von verschiedenen verwandten Entitäten (Referrern) verwendet werden. In diesem Fall handelt es sich möglicherweise um nicht hierarchische Daten, die zur Identifizierung einzelner Entitäten verwendet werden. In anderen Fällen werden möglicherweise nur bestimmte Variablen / Felder - bestimmte Komponenten eindeutiger Indizes - angegeben und eine Liste / ein Satz von Datensätzen abgerufen. In solchen Fällen ist es möglicherweise einfacher, logischer und sinnvoller, die URLs als QueryParams zu implementieren!

Könnte eine lange hexadezimale Zeichenfolge den Wert von Schlüsselwörtern im Rest des Pfads verwässern / verringern? Es könnte sich lohnen die möglichen SEO-Auswirkungen der Platzierung von Variablen / Werten im Pfad oder in der Abfrage berücksichtigenund die Auswirkungen auf die Benutzeroberfläche, ob Benutzer die Hierarchie von URLs durch Bearbeiten des Inhalts der Adressleiste durchlaufen / erkunden können sollen. Meine 404 Not Found-Seite verwendet SSI-Variablen, um defekte URLs automatisch an ihre Eltern weiterzuleiten! Suchroboter können auch die Pfadhierarchie durchlaufen. Auf der anderen Seite entferne ich persönlich, wenn ich URLs in sozialen Medien teile, alle privaten eindeutigen Kennungen manuell - normalerweise durch Abschneiden der Abfrage von der URL, wobei nur der Pfad übrig bleibt. In diesem Fall ist es nützlich, eindeutige Kennungen zu platzieren im Pfad und nicht in der Abfrage. Ob wir die Verwendung von Pfadkomponenten als grobe Benutzeroberfläche erleichtern möchten, hängt möglicherweise davon ab, ob die Daten / Komponenten für Menschen lesbar sind oder nicht. Die Frage der menschlichen Lesbarkeit bezieht sich etwas auf die Frage der Hierarchie: oft, Daten, die als für Menschen lesbare Schlüsselwörter ausgedrückt werden können, sind ebenfalls hierarchisch. Hierarchische Daten können häufig als lesbare Schlüsselwörter ausgedrückt werden. (Suchmaschinen selbst können so definiert werden, dass sie die Verwendung von URLs als Benutzeroberfläche erweitern.) Hierarchien von Schlüsselwörtern oder Direktiven sind möglicherweise nicht streng geordnet, aber sie sind normalerweise so nah, dass wir alternative Fälle im Pfad abdecken könnenBeschriften Sie eine Option als "kanonischen" Fall .

Grundsätzlich gibt es verschiedene Arten von Fragen, die wir mit der URL für jede Anfrage beantworten können:

  1. Welche Art von Aufzeichnung / Sache fordern / dienen wir?
  2. Für welche interessieren wir uns?
  3. Wie wollen wir die Informationen / Aufzeichnungen präsentieren?

Q1 wird mit ziemlicher Sicherheit am besten vom Pfad oder von PathParams abgedeckt. Q3 (das wahrscheinlich über einen Satz beliebig geordneter optionaler Parameter und Standardwerte gesteuert wird); wird mit ziemlicher Sicherheit am besten von QueryParams abgedeckt. F2: Es kommt darauf an ...

Matthew Slyman
quelle
2

Sie können sowohl Abfrageparameter als auch Pfadparameter unterstützen, z. B. bei der Aggregation von Ressourcen - wenn die Erfassung von Unterressourcen für sich genommen sinnvoll ist.

/departments/{id}/employees
/employees?dept=id

Abfrageparameter können hierarchische und nicht hierarchische Teilmengen unterstützen. Pfadparameter sind nur hierarchisch.

Ressourcen können mehrere Hierarchien aufweisen. Unterstützen Sie kurze Pfade, wenn Sie breite Untersammlungen abfragen, die hierarchische Grenzen überschreiten.

/inventory?make=toyota&model=corolla
/inventory?year=2014

Verwenden Sie Abfrageparameter, um orthogonale Hierarchien zu kombinieren.

/inventory/makes/toyota/models/corolla?year=2014
/inventory/years/2014?make=toyota&model=corolla
/inventory?make=toyota&model=corolla&year=2014

Verwenden Sie bei der Komposition nur Pfadparameter - wenn eine Ressource keinen Sinn ergibt, wenn sie von ihrer übergeordneten Ressource getrennt ist und die globale Sammlung aller untergeordneten Ressourcen an sich keine nützliche Ressource ist.

/words/{id}/definitions
/definitions?word=id   // not useful
Steve Mitchell
quelle
1

Der Grund ist eigentlich sehr einfach. Wenn Sie einen Abfrageparameter verwenden, können Sie Zeichen wie "/" eingeben, und Ihr Client muss diese nicht in HTML codieren. Es gibt andere Gründe, aber das ist ein einfaches Beispiel. Wann wird eine Pfadvariable verwendet? Ich würde sagen, wann immer Sie mit IDs zu tun haben oder ob die Pfadvariable eine Richtung für eine Abfrage ist.

Tony
quelle
1

Ich gebe ein Beispiel für Untersand, wann wir @Queryparamund verwenden@pathparam

Zum Beispiel nehme ich eine Ressource ist carResourceKlasse

Wenn Sie die Eingaben Ihrer Ressourcenmethode manuell festlegen möchten, verwenden Sie den Parametertyp als @pathaparam. Wenn die Eingaben Ihrer Ressourcenmethode optional sein sollen, behalten Sie diesen Parametertyp als @QueryParamParameter bei

@Path("/car")
class CarResource
{
    @Get
    @produces("text/plain")
    @Path("/search/{carmodel}")
    public String getCarSearch(@PathParam("carmodel")String model,@QueryParam("carcolor")String color) {
        //logic for getting cars based on carmodel and color
            -----
        return cars
    }
}

Für diese Ressource die Anfrage weiterleiten

req uri ://address:2020/carWeb/car/search/swift?carcolor=red

Wenn Sie eine solche Anforderung stellen, gibt die Ressource das basierte Automodell und die Farbe an

 req uri://address:2020/carWeb/car/search/swift

Wenn Sie eine solche Anforderung stellen, zeigt die Resoce-Methode nur ein schnelles modellbasiertes Auto an

req://address:2020/carWeb/car/search?carcolor=red

Wenn Sie so angeben, erhalten wir die ResourceNotFound-Ausnahme, da ich in der Klasse für Fahrzeugressourcen @pathPramdas Carmodel als reQ uri deklariert habe und angeben sollte und sollte Außerdem wird die Anforderung an die Ressource übergeben, warum, da die Farbe @quetyParamin der Anforderung optional ist.

DB5
quelle
0
  1. @QueryParam kann bequem mit der Annotation Standardwert verwendet werden, sodass Sie eine Nullzeigerausnahme vermeiden können, wenn kein Abfrageparameter übergeben wird.

Wenn Sie Abfrageparameter aus einer GET-Anforderung analysieren möchten, können Sie einfach den entsprechenden Parameter für die Methode definieren, die die GET-Anforderung verarbeitet, und sie mit @QueryParamAnmerkungen versehen

  1. @PathParamextrahiert die URI-Werte und stimmt mit überein @Path. Und erhält daher den Eingabeparameter. 2.1 @PathParamkann mehr als eins sein und ist auf Methodenargumente festgelegt

    @Path("/rest")
    public class Abc {
    
        @GET
        @Path("/msg/{p0}/{p1}")
        @Produces("text/plain")
        public String add(@PathParam("p0") Integer param1, @PathParam("p1")  Integer param2 )
        {
            return String.valueOf(param1+param2);
        }
    } 

In dem obigen Beispiel
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0Spiele param1und p1Streichhölzer param2. Also für den URI
http://localhost:8080/Restr/rest/msg/4/6,
erhalten wir das Ergebnis 10.

In REST - Service, JAX-RS bietet @QueryParamund @FormParamsowohl für die Daten von HTTP - Anfrage zu akzeptieren. Ein HTTP-Formular kann mit verschiedenen Methoden wie GET und POST gesendet werden.

@QueryParam : Akzeptiert die GET-Anforderung und liest Daten aus der Abfragezeichenfolge.

@FormParam: Akzeptiert POST-Anforderungen und ruft Daten aus dem HTML-Formular oder einer Anforderung des Mediums ab

Amlesh Kumar
quelle
0

Kurz gesagt,

@Pathparam Funktioniert für Werte, die sowohl Ressourcen als auch Abfragezeichenfolgen durchlaufen

  • /user/1
  • /user?id=1

@Queryparam funktioniert nur für Werte, die eine Abfragezeichenfolge übergeben

  • /user?id=1
ArulRajP
quelle