Parámetros de matriz de URL frente a parámetros de consulta

176

Me pregunto si usar parámetros de matriz o consulta en mis URL. Encontré una discusión anterior sobre ese tema no satisfactoria.

Ejemplos

A primera vista, los parámetros de matriz parecen tener solo ventajas:

  • más legible
  • no se requiere codificación ni decodificación de "&" en documentos XML
  • URL con "?" no se almacenan en caché en muchos casos; Las URL con parámetros de matriz se almacenan en caché
  • los parámetros de la matriz pueden aparecer en todas partes en la ruta y no se limitan a su final
  • Los parámetros de la matriz pueden tener más de un valor: paramA=val1,val2

Pero también hay desventajas:

  • solo unos pocos marcos como JAX-RS admiten parámetros de matriz
  • Cuando un navegador envía un formulario a través de GET, los parámetros se convierten en parámetros de consulta. Por lo tanto, termina en dos tipos de parámetros para la misma tarea. Para no confundir a los usuarios de los servicios REST y limitar el esfuerzo para los desarrolladores de los servicios, sería más fácil usar siempre parámetros de consulta, en esta área.

Dado que el desarrollador del servicio puede elegir un marco con soporte de matriz de parámetros, la única desventaja restante sería que los navegadores crean por defecto los parámetros de consulta.

¿Hay alguna otra desventaja? ¿Qué harías?

deamon
fuente
10
No estoy seguro de cuál es el gran problema con las URL de matriz. Según el artículo de diseño de W3C que escribió TBL, que era sólo una idea de diseño y declara explícitamente que es no una característica de la web. Cosas como las URL relativas no se implementan al usarlo. Si quieres usarlo, está bien; simplemente no hay una forma estándar de usarlo porque no es un estándar.
Steve Pomeroy
2
@Steve Pomeroy: ¿Es este el artículo que mencionas: w3.org/DesignIssues/MatrixURIs.html
Marcel
3
@ Marcel: sí. Para aquellos que piensan en las URL de matriz, tenga en cuenta el "Estado: vista personal" en la parte superior del documento.
Steve Pomeroy
¿pueden los parámetros de matriz tener más de un valor? ¿De Verdad?
Ayyash

Respuestas:

212

La diferencia importante es que los parámetros de la matriz se aplican a un elemento de ruta particular, mientras que los parámetros de consulta se aplican a la solicitud como un todo. Esto entra en juego cuando se realiza una consulta compleja de estilo REST a múltiples niveles de recursos y subrecursos:

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

Realmente se reduce al espacio de nombres.

Nota: Los 'niveles' de recursos aquí son categoriesy objects.

Si solo se usaran parámetros de consulta para una URL de varios niveles, terminaría con

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

De esta manera, también perdería la claridad agregada por la localidad de los parámetros dentro de la solicitud. Además, cuando se utiliza un marco como JAX-RS, todos los parámetros de consulta aparecerían dentro de cada manejador de recursos, lo que generaría conflictos y confusión potenciales.

Si su consulta tiene solo un "nivel", entonces la diferencia no es realmente importante y los dos tipos de parámetros son efectivamente intercambiables, sin embargo, los parámetros de consulta generalmente son mejor soportados y más ampliamente reconocidos. En general, le recomendaría que se apegue a los parámetros de consulta para cosas como formularios HTML y API HTTP simples de un solo nivel.

Tim Sylvester
fuente
2
irrelativo: ¿ /?parte representa un recurso?
Jin Kwon el
77
El ?inicia el parámetro de consulta parte de la solicitud. Los parámetros de consulta son el tipo más común de parámetros de URL, a diferencia de los parámetros de matriz. La barra diagonal antes del signo de interrogación asegura que el parámetro de consulta pageno se ejecute en el parámetro de matriz que precede a la barra diagonal. Supongo que si no hubiera parámetros de matriz adjuntos categories, los parámetros de consulta podrían adjuntarse sin la barra como esta:http://example.com/res/categories?page=1
Teemu Leisti
8
Si bien es cierto que los parámetros de la matriz pueden especificarse en cualquier segmento de ruta, JAX-RS, por ejemplo, no los asocia con el segmento de ruta al que se agregaron al inyectar @MatrixParam. Según "Restful Java with JAX-RS 2.0", una solicitud como "GET / mercedes / e55; color = black / 2006 / interior; color = tan" tendría una definición ambigua del parámetro de matriz de color. Aunque parece que si procesas cada PathSegment individualmente, puedes resolverlo ... Tan útil pero más trabajo para lograrlo que si especificase categoryName = foo; objectName = green.
UFL1138
15

Además de la respuesta de Tim Sylvester, me gustaría proporcionar un ejemplo de cómo se pueden manejar los parámetros de la matriz con JAX-RS .

  1. Parámetros matriciales en el último elemento de recurso

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

    Puedes acceder a ellos usando la @MatrixParamanotación

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

    Respuesta

    green

    Pero como los estados de Javadoc

    Tenga en cuenta que el @MatrixParamvalor de la anotación se refiere al nombre de un parámetro de matriz que reside en el último segmento de ruta coincidente de la estructura Java anotada de ruta que inyecta el valor del parámetro de matriz.

    ... lo que nos lleva al punto 2

  2. Parámetros de matriz en el medio de una URL

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

    Puede acceder a los parámetros de la matriz en cualquier lugar utilizando variables de ruta y @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;
    }
    

    Respuesta

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

    Como los parámetros de la matriz se proporcionan como un MultivaluedMap, puede acceder a cada uno de ellos mediante

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

    o si solo necesitas el primero

    String name = matrixParameters.getFirst("name");
  3. Obtenga todos los parámetros de la matriz como un parámetro de método

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

    Usa a List<PathSegment>para conseguirlos a todos

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

    Respuesta

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

Demasiado importante para ser relegado a la sección de comentarios.

No estoy seguro de cuál es el gran problema con las URL de matriz. Según el artículo de diseño de w3c que escribió TBL, era solo una idea de diseño y afirma explícitamente que no es una característica de la web. Cosas como las URL relativas no se implementan al usarlo. Si quieres usarlo, está bien; simplemente no hay una forma estándar de usarlo porque no es un estándar. - Steve Pomeroy

Entonces, la respuesta corta es, si necesita RS para fines comerciales, es mejor que use el parámetro de solicitud.

Ajeet Ganga
fuente
55
¡Alguien le dijo eso a los desarrolladores de Angular 2 que decidieron que eran tan únicos que necesitaban implementar esto!
Matt Pileggi
2
@MattPileggi También estoy leyendo esto debido a Angular 2. Casi todos los aspectos de Angular 2 son altamente especializados, poco convencionales y están en desacuerdo con los patrones de uso existentes. Todavía no se ha comprobado que esto agrega un valor atenuante.
Aluan Haddad
1
Entonces, chicos, también estoy aquí por la misma razón, pero permítanme agregar algunos puntos a esta discordancia con este problema sobre la matriz de URL y Google Analytis en la página de github del equipo angular 2: github.com/angular/angular/issues/11740 Pero Después de algunas investigaciones al respecto, la notación de matriz de URL parece ser más legible para los humanos que los parámetros de consulta de url , principalmente cuando necesitamos algún parámetro en el medio o url (no solo al final).
Richard Lee
8
Supongo que todos los que piensan que esto no es estándar tampoco están familiarizados con la especificación de la plantilla uri. La codificación de objetos complejos en parámetros de ruta es una característica muy útil de las plantillas uri; el hecho de que la mayoría de la gente no lo conozca o lo use no significa que sea una conspiración malvada por parte de desarrolladores angulares para inyectar una complejidad inútil en su vida.
Ajax
2
Pffft - "<lo que no sabía que existía hasta ahora> no es estándar, por lo que se preserva la aceptabilidad de mi ignorancia". Lo que TBL hizo o no decidió hacer con una idea es en gran medida irrelevante. No era una característica de su web en 2001. Las características de la web son las que el cliente y los implementadores del servidor elijan. Si Angular admite parámetros de matriz y JAX-RS los admite y estas son las herramientas de implementación elegidas, continúe y use lo que funciona.
Dave