web-dev-qa-db-fra.com

Paramètres de matrice d'URL par rapport aux paramètres de demande

Je me demande s'il faut utiliser des paramètres de matrice ou de requête dans mes URL. J'ai trouvé un ancien discussion à ce sujet ne satisfaisant pas.

Exemples

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

  • plus lisible
  • aucun codage et 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 les paramètres de matrice sont mises en cache
  • les paramètres de matrice peuvent apparaître partout dans le chemin et ne se limitent pas à 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 tels que 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. Donc, il se termine dans deux types de paramètres pour la même tâche. Pour ne pas confondre les utilisateurs des services REST et limiter les efforts des développeurs de 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 une structure avec un support de 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?

168
deamon

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 demande dans son ensemble. Cela entre en jeu lors de la création d'une requête complexe de type REST sur plusieurs niveaux de ressources et sous-ressources:

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

Cela dépend vraiment de l'espacement des noms. Si seuls des paramètres de requête étaient utilisés, vous obtiendriez des paramètres tels que "nom_catégorie" et "nom_objet" et vous perdriez la clarté ajoutée par la localité des paramètres dans la requête. En outre, lors de l'utilisation d'une infrastructure telle que JAX-RS, tous les paramètres de requête apparaissent dans chaque gestionnaire de ressources, ce qui peut entraîner des conflits et de la confusion.

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

201
Tim Sylvester

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

Je ne sais pas quel est le problème avec les URL de matrice. Selon l'article sur le design du w3c écrit par TBL, il s'agissait simplement d'une idée de design et indiquait explicitement que ce n'était 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 bien; il n'y a pas de moyen standard de l'utiliser car ce n'est pas une norme. - Steve Pomeroy

La réponse est donc courte: si vous avez besoin de RS à des fins commerciales, utilisez plutôt le paramètre request.

10
Ajeet Ganga

En plus de la réponse de Tim Sylvester , j'aimerais vous donner un exemple de la manière dont les paramètres de matrice peuvent être gérés avec JAX -RS.

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

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

    Vous pouvez y accéder en utilisant @MatrixParam annotation

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

    Réponse

    green
    

    Mais comme les états de Javadoc

    Notez que le @MatrixParam La valeur d’annotation fait référence au nom d’un paramètre de matrice qui réside dans le dernier segment de chemin correspondant du chemin annoté Java structure 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 la matrice n’importe où en utilisant les variables de chemin et @PathParamPathSegment .

    @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]
    

    Les paramètres de la matrice étant fournis sous forme de MultivaluedMap , vous pouvez accéder à chacun d'eux en

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

    ou si vous avez seulement besoin du premier

    String name = matrixParameters.getFirst("name");
    
  3. Récupère tous les paramètres de la matrice sous la forme d'un paramètre de méthode

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

    Utiliser un List<PathSegment> pour tous les obtenir

    @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]
    
8
René Link