URL-Matrixparameter vs. Abfrageparameter

176

Ich frage mich, ob ich Matrix- oder Abfrageparameter in meinen URLs verwenden soll. Ich fand eine ältere Diskussion zu diesem Thema nicht zufriedenstellend.

Beispiele

Auf den ersten Blick scheinen Matrixparameter nur Vorteile zu haben:

  • besser lesbar
  • Es ist keine Codierung und Decodierung von "&" in XML-Dokumenten erforderlich
  • URLs mit "?" werden in vielen Fällen nicht zwischengespeichert; URLs mit Matrixparametern werden zwischengespeichert
  • Matrixparameter können überall im Pfad erscheinen und sind nicht auf sein Ende beschränkt
  • Matrixparameter können mehr als einen Wert haben: paramA=val1,val2

Es gibt aber auch Nachteile:

  • Nur wenige Frameworks wie JAX-RS unterstützen Matrixparameter
  • Wenn ein Browser ein Formular über GET sendet, werden die Parameter zu Abfrageparametern. Es gibt also zwei Arten von Parametern für dieselbe Aufgabe. Um die Benutzer der REST-Services nicht zu verwirren und den Aufwand für die Entwickler der Services zu begrenzen, ist es einfacher, immer Abfrageparameter zu verwenden - in diesem Bereich.

Da der Entwickler des Dienstes ein Framework mit Unterstützung für Matrixparameter auswählen kann, besteht der einzige verbleibende Nachteil darin, dass Browser standardmäßig Abfrageparameter erstellen.

Gibt es noch andere Nachteile? Was würden Sie tun?

Deamon
quelle
10
Ich bin mir nicht sicher, was die große Sache mit Matrix-URLs ist. Laut dem von TBL verfassten w3c-Designartikel war es nur eine Designidee und besagt ausdrücklich, dass es sich nicht um eine Funktion des Webs handelt. Dinge wie relative URLs werden bei der Verwendung nicht implementiert. Wenn Sie es verwenden möchten, ist das in Ordnung; Es gibt einfach keine Standardmethode, weil es kein Standard ist.
Steve Pomeroy
2
@ Steve Pomeroy: Ist dies der Artikel, den Sie erwähnen: w3.org/DesignIssues/MatrixURIs.html
Marcel
3
@ Marcel: Ja. Wenn Sie über Matrix-URLs nachdenken, beachten Sie den "Status: Persönliche Ansicht" oben im Dokument.
Steve Pomeroy
Können Matrixparameter mehr als einen Wert haben? Ja wirklich?
Ayyash

Antworten:

211

Der wichtige Unterschied besteht darin, dass Matrixparameter für ein bestimmtes Pfadelement gelten, während Abfrageparameter für die gesamte Anforderung gelten. Dies kommt zum Tragen, wenn eine komplexe Abfrage im REST-Stil für mehrere Ebenen von Ressourcen und Unterressourcen durchgeführt wird:

http://example.com/res/categories;name=foo/objects;name=green/?page=1

Es kommt wirklich auf den Namespace an.

Hinweis: Die Ressourcenebenen hier sind categoriesund objects.

Wenn nur Abfrageparameter für eine mehrstufige URL verwendet würden, würden Sie am Ende erhalten

http://example.com/res?categories_name=foo&objects_name=green&page=1

Auf diese Weise verlieren Sie auch die Klarheit, die durch die Lokalität der Parameter in der Anforderung entsteht. Wenn Sie ein Framework wie JAX-RS verwenden, werden außerdem alle Abfrageparameter in jedem Ressourcenhandler angezeigt, was zu potenziellen Konflikten und Verwirrung führen kann.

Wenn Ihre Abfrage nur eine "Ebene" hat, ist der Unterschied nicht wirklich wichtig und die beiden Arten von Parametern sind effektiv austauschbar. Abfrageparameter werden jedoch im Allgemeinen besser unterstützt und allgemein anerkannt. Im Allgemeinen würde ich empfehlen, dass Sie sich an Abfrageparameter für Dinge wie HTML-Formulare und einfache einstufige HTTP-APIs halten.

Tim Sylvester
quelle
2
irrelavant: Stellt ein /?Teil eine Ressource dar?
Jin Kwon
7
Das ?startet den Abfrageparameterteil der Anfrage. Abfrageparameter sind im Gegensatz zu Matrixparametern die häufigste Art von URL-Parametern. Der Schrägstrich vor dem Fragezeichen stellt sicher, dass der Abfrageparameter pagenicht auf den Matrixparameter vor dem Schrägstrich trifft. Ich nehme an, wenn keine categorieshttp://example.com/res/categories?page=1
Matrixparameter
8
Während es stimmt, dass die Matrixparameter in jedem Pfadsegment angegeben werden können, ordnet JAX-RS sie beispielsweise nicht dem Pfadsegment zu, an das sie beim Injizieren mit @MatrixParam angehängt wurden. Laut "Restful Java with JAX-RS 2.0" hätte eine Anfrage wie "GET / mercedes / e55; color = black / 2006 / interior; color = tan" eine mehrdeutige Definition des Farbmatrixparameters. Obwohl es so aussieht, als ob Sie jedes PathSegment einzeln verarbeiten, können Sie es herausfinden ... So nützlich, aber mehr Arbeit, um dorthin zu gelangen, als wenn Sie categoryName = foo; objectName = green angegeben haben.
UFL1138
15

Neben der Antwort von Tim Sylvester möchte ich ein Beispiel geben, wie Matrixparameter mit JAX-RS behandelt werden können .

  1. Matrixparameter am letzten Ressourcenelement

    http://localhost:8080/res/categories/objects;name=green

    Sie können über die @MatrixParamAnmerkung darauf zugreifen

    @GET
    @Path("categories/objects")
    public String objects(@MatrixParam("name") String objectName) {
      return objectName;
    }

    Antwort

    green

    Aber wie die Javadoc-Staaten

    Beachten Sie, dass sich der @MatrixParamAnnotationswert auf einen Namen eines Matrixparameters bezieht, der sich im letzten übereinstimmenden Pfadsegment der mit Pfaden annotierten Java-Struktur befindet, die den Wert des Matrixparameters einfügt.

    ... was uns zu Punkt 2 bringt

  2. Matrixparameter in der Mitte einer URL

    http://localhost:8080/res/categories;name=foo/objects;name=green

    Sie können mit Pfadvariablen und überall auf Matrixparameter zugreifen @PathParam PathSegment.

    @GET
    @Path("{categoryVar:categories}/objects")
    public String objectsByCategory(@PathParam("categoryVar") PathSegment categorySegment, 
                                    @MatrixParam("name") String objectName) {
      MultivaluedMap<String, String> matrixParameters = categorySegment.getMatrixParameters();
      String categorySegmentPath = categorySegment.getPath();
      String string = String.format("object %s, path:%s, matrixParams:%s%n", objectName,
              categorySegmentPath, matrixParameters);
      return string;
    }

    Antwort

    object green, path:categories, matrixParams:[name=foo]

    Da die Matrixparameter als bereitgestellt werden MultivaluedMap, können Sie jeweils auf zugreifen

    List<String> names = matrixParameters.get("name");

    oder wenn Sie nur den ersten brauchen

    String name = matrixParameters.getFirst("name");
  3. Holen Sie sich alle Matrixparameter als einen Methodenparameter

    http://localhost:8080/res/categories;name=foo/objects;name=green//attributes;name=size

    Verwenden Sie a List<PathSegment>, um sie alle zu erhalten

    @GET
    @Path("all/{var:.+}")
    public String allSegments(@PathParam("var") List<PathSegment> pathSegments) {
      StringBuilder sb =  new StringBuilder();
    
      for (PathSegment pathSegment : pathSegments) {
        sb.append("path: ");
        sb.append(pathSegment.getPath());
        sb.append(", matrix parameters ");
        sb.append(pathSegment.getMatrixParameters());
        sb.append("<br/>");
      }
    
      return sb.toString();
    }

    Antwort

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]
René Link
quelle
10

--Zu wichtig, um in den Kommentarbereich verbannt zu werden .--

Ich bin mir nicht sicher, was die große Sache mit Matrix-URLs ist. Laut dem von TBL verfassten w3c-Designartikel war es nur eine Designidee und besagt ausdrücklich, dass es sich nicht um eine Funktion des Webs handelt. Dinge wie relative URLs werden bei der Verwendung nicht implementiert. Wenn Sie es verwenden möchten, ist das in Ordnung; Es gibt einfach keine Standardmethode, weil es kein Standard ist. - Steve Pomeroy

Die kurze Antwort lautet also: Wenn Sie RS für geschäftliche Zwecke benötigen, ist es besser, den Anforderungsparameter zu verwenden.

Ajeet Ganga
quelle
5
Jemand sagt dies Angular 2-Entwicklern, die entschieden haben, dass sie so einzigartig sind, dass sie dies stattdessen implementieren müssen!
Matt Pileggi
2
@MattPileggi Ich lese dies auch wegen Angular 2. Fast jeder Aspekt von Angular 2 ist hochspezialisiert, unkonventionell und steht im Widerspruch zu bestehenden Nutzungsmustern. Es ist noch nicht bewiesen, dass dies einen mildernden Wert hinzufügt.
Aluan Haddad
1
Also Leute, ich bin auch aus dem gleichen Grund hier, aber lassen Sie mich einige Punkte zu dieser Diskussion mit diesem Problem über URL-Matrix und Google Analytis auf der Github-Seite des Angular 2-Teams hinzufügen: github.com/angular/angular/issues/11740 Aber Nach einigen Recherchen scheint die URL-Matrix-Notation besser lesbar zu sein als die URL-Abfrageparameter , hauptsächlich wenn wir einen Parameter in der Mitte oder URL benötigen (nicht nur am Ende).
Richard Lee
8
Ich denke, jeder, der denkt, dass dies nicht Standard ist, ist auch nicht mit der Uri-Template-Spezifikation vertraut? Das Codieren komplexer Objekte in Pfadparametern ist eine sehr nützliche Funktion von Uri-Vorlagen. Nur weil die meisten Menschen nichts davon wissen oder es nicht benutzen, heißt das nicht, dass es eine böse Verschwörung von eckigen Entwicklern ist, Ihrem Leben nutzlose Komplexität zu verleihen.
Ajax
2
Pffft - "<was ich bis jetzt nicht wusste, dass es existiert> ist nicht standardisiert, wodurch die Akzeptanz meiner Unwissenheit erhalten bleibt ". Was TBL mit einer Idee gemacht hat oder nicht, ist weitgehend unerheblich. Es war keine Funktion seines Webs im Jahr 2001. Die Funktionen des Webs sind unabhängig davon, wie die Client- und Server-Implementierer sie auswählen. Wenn Angular Matrixparameter unterstützt und JAX-RS diese unterstützt und Sie diese Implementierungstools ausgewählt haben, verwenden Sie das, was funktioniert.
Dave