Paramètres de matrice d'URL et paramètres de requête

176

Je me demande s'il faut utiliser des paramètres de matrice ou de requête dans mes URL. J'ai trouvé une discussion plus ancienne sur ce sujet pas satisfaisante.

Exemples

À première vue, les paramètres de matrice semblent n'avoir que des avantages:

  • plus lisible
  • aucun encodage ni décodage de «&» dans les documents XML n'est requis
  • URL avec "?" ne sont pas mis en cache dans de nombreux cas; Les URL avec des paramètres de matrice sont mises en cache
  • les paramètres de la matrice peuvent apparaître partout dans le chemin et ne sont pas limités à sa fin
  • Les paramètres de matrice peuvent avoir plusieurs valeurs: paramA=val1,val2

Mais il y a aussi des inconvénients:

  • seuls quelques frameworks comme JAX-RS prennent en charge les paramètres de matrice
  • Lorsqu'un navigateur soumet un formulaire via GET, les paramètres deviennent des paramètres de requête. Cela se termine donc par deux types de paramètres pour la même tâche. Pour ne pas confondre les utilisateurs des services REST et limiter l'effort des développeurs des services, il serait plus facile d'utiliser toujours les paramètres de requête - dans ce domaine.

Étant donné que le développeur du service peut choisir un cadre avec la prise en charge des paramètres de matrice, le seul inconvénient restant serait que les navigateurs créent par défaut des paramètres de requête.

Y a-t-il d'autres inconvénients? Qu'est-ce que tu ferais?

démon
la source
10
Je ne sais pas quel est le problème avec les URL matricielles. Selon l'article sur la conception du w3c que TBL a écrit, il ne s'agissait que d'une idée de conception et déclare explicitement que ce n'est pas une fonctionnalité du Web. Des choses comme les URL relatives ne sont pas implémentées lors de son utilisation. Si vous voulez l'utiliser, c'est très bien; il n'y a tout simplement pas de manière standard de l'utiliser car ce n'est pas une norme.
Steve Pomeroy
2
@Steve Pomeroy: Est-ce l'article que vous mentionnez: w3.org/DesignIssues/MatrixURIs.html
Marcel
3
@Marcel: oui. Pour ceux qui pensent aux URL matricielles, notez le "Statut: vue personnelle" en haut du document.
Steve Pomeroy
les paramètres de matrice peuvent-ils avoir plus d'une valeur? vraiment?
Ayyash

Réponses:

212

La différence importante est que les paramètres de matrice s'appliquent à un élément de chemin particulier tandis que les paramètres de requête s'appliquent à la requête dans son ensemble. Cela entre en jeu lors de la création d'une requête complexe de style REST vers plusieurs niveaux de ressources et sous-ressources:

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

Cela se résume vraiment à l'espacement des noms.

Remarque: les `` niveaux '' de ressources ici sont categoriesetobjects .

Si seuls les paramètres de requête étaient utilisés pour une URL à plusieurs niveaux, vous vous retrouveriez avec

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

De cette façon, vous perdriez également la clarté ajoutée par la localité des paramètres dans la demande. De plus, lors de l'utilisation d'un framework tel que JAX-RS, tous les paramètres de requête apparaissaient dans chaque gestionnaire de ressources, ce qui entraînerait des conflits potentiels et de la confusion.

Si votre requête n'a qu'un seul "niveau", alors la différence n'est pas vraiment importante et les deux types de paramètres sont effectivement interchangeables, cependant, les paramètres de requête sont généralement mieux pris en charge et plus largement reconnus. En général, je vous recommande de vous en tenir aux paramètres de requête pour des éléments tels que les formulaires HTML et les API HTTP simples à un niveau.

Tim Sylvester
la source
2
irrelavant: une /?partie représente-t-elle une ressource?
Jin Kwon
7
Le ?démarre la partie paramètre de requête de la demande. Les paramètres de requête sont le type le plus courant de paramètres d'URL, par opposition aux paramètres de matrice. La barre oblique avant le point d'interrogation garantit que le paramètre de requête pagene s'exécute pas dans le paramètre de matrice qui précède la barre oblique. Je suppose que s'il n'y avait pas de paramètres de matrice attachés categories, les paramètres de requête pourraient être attachés sans la barre oblique comme ceci:http://example.com/res/categories?page=1
Teemu Leisti
8
S'il est vrai que les paramètres de matrice peuvent être spécifiés dans n'importe quel segment de chemin, JAX-RS par exemple ne les associe pas au segment de chemin auquel ils ont été ajoutés lors de l'injection avec @MatrixParam. Selon "Restful Java with JAX-RS 2.0", une requête comme "GET / mercedes / e55; color = black / 2006 / interior; color = tan" aurait une définition ambiguë du paramètre de matrice de couleurs. Bien qu'il semble que si vous traitez chaque PathSegment individuellement, vous pouvez le comprendre ... Tellement utile mais plus de travail pour y arriver que si vous spécifiez categoryName = foo; objectName = green.
UFL1138
15

En plus de la réponse de Tim Sylvester, je voudrais donner un exemple de la manière dont les paramètres de matrice peuvent être traités avec JAX-RS .

  1. Paramètres de la matrice au dernier élément de ressource

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

    Vous pouvez y accéder en utilisant l' @MatrixParamannotation

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

    Réponse

    green

    Mais comme les états Javadoc

    Notez que la @MatrixParamvaleur d'annotation fait référence au nom d'un paramètre de matrice qui réside dans le dernier segment de chemin correspondant de la structure Java annotée par chemin qui injecte la valeur du paramètre de matrice.

    ... ce qui nous amène au point 2

  2. Paramètres de matrice au milieu d'une URL

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

    Vous pouvez accéder aux paramètres de matrice n'importe où à l'aide des variables de chemin et @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;
    }

    Réponse

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

    Étant donné que les paramètres de la matrice sont fournis comme un, MultivaluedMapvous pouvez accéder à chacun par

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

    ou si vous n'avez besoin que du premier

    String name = matrixParameters.getFirst("name");
  3. Obtenez tous les paramètres de matrice comme un paramètre de méthode

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

    Utilisez un List<PathSegment>pour les obtenir tous

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

    Réponse

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

- Trop important pour être relégué à la section des commentaires.

Je ne sais pas quel est le problème avec les URL matricielles. Selon l'article sur la conception du w3c que TBL a écrit, il ne s'agissait que d'une idée de conception et déclare explicitement que ce n'est pas une fonctionnalité du Web. Des choses comme les URL relatives ne sont pas implémentées lors de son utilisation. Si vous voulez l'utiliser, c'est très bien; il n'y a tout simplement pas de manière standard de l'utiliser car ce n'est pas une norme. - Steve Pomeroy

Donc, la réponse courte est, si vous avez besoin de RS à des fins commerciales, il vaut mieux utiliser le paramètre de demande.

Ajeet Ganga
la source
5
Quelqu'un dit cela aux développeurs Angular 2 qui ont décidé qu'ils étaient si uniques qu'ils devaient implémenter cela à la place!
Matt Pileggi
2
@MattPileggi Je lis aussi ceci à cause d'Angular 2. Presque tous les aspects d'Angular 2 sont hautement spécialisés, non conventionnels et en contradiction avec les modèles d'utilisation existants. Il n'est pas encore prouvé que cela ajoute une valeur atténuante.
Aluan Haddad
1
Alors les gars, je suis ici pour la même raison aussi, mais permettez-moi d'ajouter quelques points à cette discussion avec ce problème sur la matrice d'url et Google Analytics sur la page github de l'équipe angular 2: github.com/angular/angular/issues/11740 Mais après quelques recherches à ce sujet, la notation de la matrice d'url semble être plus lisible par l'homme que les paramètres de requête d'url , principalement lorsque nous avons besoin d'un paramètre au milieu ou à l'url (pas seulement à la fin).
Richard Lee
8
Je suppose que tous ceux qui pensent que ce n'est pas standard ne connaissent pas non plus la spécification du modèle d'URI? L'encodage d'objets complexes dans des paramètres de chemin est une fonctionnalité très utile des modèles d'URI; ce n'est pas parce que la plupart des gens ne connaissent pas ou ne l'utilisent pas qu'il s'agit d'une conspiration maléfique de développeurs angulaires pour injecter une complexité inutile dans votre vie.
Ajax
2
Pffft - "<chose dont je ne savais pas l'existence jusqu'à présent> est non standard préservant ainsi l'acceptabilité de mon ignorance". Ce que TBL a fait ou n'a pas décidé de faire avec une idée est en grande partie sans importance. Ce n'était pas une caractéristique de son site Web en 2001. Le caractéristiques du Web sont celles que les implémenteurs client et serveur les choisissent. Si Angular prend en charge les paramètres de matrice et que JAX-RS les prend en charge et que ce sont les outils de mise en œuvre que vous avez choisis, allez-y et utilisez ce qui fonctionne.
Dave