wake-up-neo.net

URL-Matrixparameter vs. Anforderungsparameter

Ich frage mich, ob ich Matrix- oder Abfrageparameter in meinen URLs verwenden soll. Ich fand ein älteres Diskussion zu diesem Thema nicht befriedigend.

Beispiele

Auf den ersten Blick scheinen Matrix-Parameter nur Vorteile zu haben:

  • lesbarer
  • das Kodieren und Dekodieren von "&" in XML-Dokumenten ist nicht erforderlich
  • URLs mit "?" werden in vielen Fällen nicht zwischengespeichert; URLs mit Matrixparametern werden zwischengespeichert
  • matrixparameter können überall im Pfad vorkommen und sind nicht auf deren 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. Das Ergebnis sind 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ürdest du tun?

168
deamon

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 Subressourcen erstellt wird:

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

Es kommt wirklich auf den Namensraum an. Wenn nur Abfrageparameter verwendet würden, würden Sie Parameter wie "category_name" und "object_name" erhalten, und Sie würden die Klarheit verlieren, die durch die Lokalität der Parameter in der Anforderung hinzugefügt wird. Darüber hinaus werden bei Verwendung eines Frameworks wie JAX-RS 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 Parametertypen sind effektiv austauschbar. Die Abfrageparameter werden jedoch im Allgemeinen besser unterstützt und werden allgemeiner erkannt. Im Allgemeinen würde ich empfehlen, dass Sie bei Abfrageparametern für Dinge wie HTML-Formulare und einfache einstufige HTTP-APIs bleiben.

201
Tim Sylvester

--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 handelt es sich lediglich um eine Designidee und es wird ausdrücklich darauf hingewiesen, 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 keine Standardmethode ist. - Steve Pomeroy

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

10
Ajeet Ganga

Neben der Antwort von Tim Sylvester möchte ich ein Beispiel für den Umgang mit Matrixparametern mit JAX-RS.

  1. Matrixparameter am letzten Ressourcenelement

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

    Sie können mit der Anmerkung @MatrixParam darauf zugreifen

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

    Response

    green
    

    Aber wie die Javadoc-Staaten

    Beachten Sie, dass sich der Annotationswert @MatrixParam Auf einen Namen eines Matrixparameters bezieht, der sich im letzten übereinstimmenden Pfadsegment des mit Pfadanmerkungen versehenen Pfads befindet Java Struktur, 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
    

    Über Pfadvariablen und @PathParamPathSegment können Sie überall auf Matrixparameter zugreifen.

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

    Response

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

    Da die Matrixparameter als MultivaluedMap bereitgestellt werden, können Sie auf jeden über zugreifen

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

    oder wenn du nur den ersten brauchst

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

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

    Verwenden Sie einen List<PathSegment>, Um 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();
    }
    

    Response

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