URL matrix parameters vs. query parameters

Viewed 82802

I'm wondering whether to use matrix or query parameters in my URLs. I found an older discussion to that topic not satisfying.

Examples

At first sight matrix params seem to have only advantages:

  • more readable
  • no encoding and decoding of "&" in XML documents is required
  • URLs with "?" are not cached in many cases; URLs with matrix params are cached
  • matrix parameters can appear everywhere in the path and are not limited to its end
  • matrix parameters can have more than one value: paramA=val1,val2

But there are also disadvantages:

  • only a few frameworks like JAX-RS support matrix parameters
  • When a browser submits a form via GET, the params become query params. So it ends up in two kinds of parameters for the same task. To not confuse users of the REST services and limit the effort for the developers of the services, it would be easier to use always query params - in this area.

Since the developer of the service can choose a framework with matrix param support, the only remaining disadvantage would be that browsers create by default query parameters.

Are there any other disadvantages? What would you do?

3 Answers

In addition to Tim Sylvester's answer I would like to provide an example of how matrix parameters can be handled with JAX-RS .

  1. Matrix parameters at the last resource element

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

    You can access them using the @MatrixParam annotation

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

    Response

    green
    

    But like the Javadoc states

    Note that the @MatrixParam annotation value refers to a name of a matrix parameter that resides in the last matched path segment of the Path-annotated Java structure that injects the value of the matrix parameter.

    ... what brings us to point 2

  2. Matrix parameters in the middle of an URL

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

    You can access matrix parameters anywhere using path variables and @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;
    }
    

    Response

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

    Since the matrix parameters are provided as a MultivaluedMap you can access each by

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

    or if you only need the first one

    String name = matrixParameters.getFirst("name");
    
  3. Get all matrix parameters as one method parameter

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

    Use a List<PathSegment> to get them all

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