Parâmetros da matriz de URL vs. parâmetros de consulta

176

Eu estou querendo saber se deve usar parâmetros de matriz ou consulta em meus URLs. Eu achei uma discussão mais antiga sobre esse tópico não satisfatória.

Exemplos

À primeira vista, os parâmetros de matriz parecem ter apenas vantagens:

  • mais legível
  • nenhuma codificação e decodificação de "&" em documentos XML é necessária
  • URLs com "?" não são armazenados em cache em muitos casos; URLs com parâmetros de matriz são armazenados em cache
  • parâmetros de matriz podem aparecer em qualquer lugar do caminho e não estão limitados ao seu final
  • parâmetros de matriz podem ter mais de um valor: paramA=val1,val2

Mas também há desvantagens:

  • apenas algumas estruturas, como JAX-RS, suportam parâmetros de matriz
  • Quando um navegador envia um formulário via GET, os parâmetros se tornam parâmetros de consulta. Portanto, acaba em dois tipos de parâmetros para a mesma tarefa. Para não confundir os usuários dos serviços REST e limitar o esforço para os desenvolvedores dos serviços, seria mais fácil usar sempre os parâmetros de consulta - nesta área.

Como o desenvolvedor do serviço pode escolher uma estrutura com suporte a parâmetros de matriz, a única desvantagem restante seria que os navegadores criem por parâmetros de consulta padrão.

Existem outras desvantagens? O que você faria?

Deamon
fonte
10
Não sei ao certo qual é o problema dos URLs da matriz. De acordo com o artigo projeto W3C que TBL escreveu, era apenas uma idéia do projeto e afirma explicitamente que é não uma característica da web. Coisas como URLs relativos não são implementadas ao usá-lo. Se você quiser usá-lo, tudo bem; simplesmente não há uma maneira padrão de usá-lo, porque não é um padrão.
Steve Pomeroy
2
@ Steve Pomeroy: Este é o artigo que você mencionou: w3.org/DesignIssues/MatrixURIs.html
Marcel
3
@Marcel: sim. Para aqueles que pensam em URLs de matriz, observe o "Status: visão pessoal" na parte superior do documento.
9788 Steve Jobs Pomeroy
os parâmetros de matriz podem ter mais de um valor? realmente?
Ayyash

Respostas:

212

A diferença importante é que os parâmetros da matriz se aplicam a um elemento de caminho específico, enquanto os parâmetros de consulta se aplicam à solicitação como um todo. Isso entra em jogo ao fazer uma consulta complexa no estilo REST para vários níveis de recursos e sub-recursos:

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

Realmente se resume ao namespacing.

Nota: Os 'níveis' de recursos aqui são categoriese objects.

Se apenas parâmetros de consulta fossem usados ​​para um URL de vários níveis, você terminaria com

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

Dessa forma, você também perderia a clareza adicionada pela localidade dos parâmetros na solicitação. Além disso, ao usar uma estrutura como JAX-RS, todos os parâmetros de consulta apareceriam em cada manipulador de recursos, levando a possíveis conflitos e confusão.

Se sua consulta tiver apenas um "nível", a diferença não será realmente importante e os dois tipos de parâmetros serão efetivamente intercambiáveis. No entanto, os parâmetros de consulta geralmente são mais bem suportados e mais amplamente reconhecidos. Em geral, eu recomendaria que você se atenha aos parâmetros de consulta para coisas como formulários HTML e APIs HTTP simples e de nível único.

Tim Sylvester
fonte
2
irrelavante: /?parte representa um recurso?
Jin Kwon
7
O ?inicia a parte parâmetro de consulta do pedido. Os parâmetros de consulta são o tipo mais comum de parâmetros de URL, em oposição aos parâmetros da matriz. A barra antes do ponto de interrogação garante que o parâmetro de consulta pagenão seja executado no parâmetro da matriz que precede a barra. Suponho que, se não houvesse parâmetros de matriz ligados a categories, os parâmetros de consulta poderia anexado sem a barra assim:http://example.com/res/categories?page=1
Teemu Leisti
8
Embora seja verdade que os parâmetros da matriz possam ser especificados em qualquer segmento de caminho, o JAX-RS, por exemplo, não os associa ao segmento de caminho ao qual foram anexados ao injetar com @MatrixParam. De acordo com "Restful Java with JAX-RS 2.0", uma solicitação como "GET / mercedes / e55; color = black / 2006 / interior; color = tan" teria uma definição ambígua dos parâmetros da matriz de cores. Embora pareça que se você processar cada PathSegment individualmente, você pode descobrir ... Tão útil, mas mais trabalho para alcançá-lo do que se você especificasse categoryName = foo; objectName = green.
UFL1138
15

Além da resposta de Tim Sylvester, gostaria de fornecer um exemplo de como os parâmetros da matriz podem ser tratados com o JAX-RS .

  1. Parâmetros da matriz no último elemento do recurso

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

    Você pode acessá-los usando a @MatrixParamanotação

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

    Resposta

    green

    Mas, como os estados Javadoc

    Observe que o @MatrixParamvalor da anotação se refere ao nome de um parâmetro da matriz que reside no último segmento de caminho correspondente da estrutura Java anotada por Path que injeta o valor do parâmetro da matriz.

    ... o que nos leva ao ponto 2

  2. Parâmetros da matriz no meio de uma URL

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

    Você pode acessar os parâmetros da matriz em qualquer lugar usando as variáveis ​​de caminho e @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;
    }

    Resposta

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

    Como os parâmetros da matriz são fornecidos como um, MultivaluedMapvocê pode acessar cada um deles.

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

    ou se você só precisa do primeiro

    String name = matrixParameters.getFirst("name");
  3. Obter todos os parâmetros da matriz como um parâmetro de método

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

    Use a List<PathSegment>para obter 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();
    }

    Resposta

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

--Muito importante ser relegado para a seção de comentários .--

Não sei ao certo qual é o problema dos URLs da matriz. De acordo com o artigo de design do w3c que a TBL escreveu, era apenas uma idéia de design e afirma explicitamente que não é um recurso da web. Coisas como URLs relativos não são implementadas ao usá-lo. Se você quiser usá-lo, tudo bem; simplesmente não há uma maneira padrão de usá-lo, porque não é um padrão. - Steve Pomeroy

Uma resposta tão curta é que, se você precisar do RS para fins comerciais, é melhor usar o parâmetro request.

Ajeet Ganga
fonte
5
Alguém disse isso aos desenvolvedores do Angular 2 que decidiram que eram tão únicos que precisavam implementar isso!
precisa saber é o seguinte
2
@MattPileggi Também estou lendo isso por causa do Angular 2. Quase todos os aspectos do Angular 2 são altamente especializados, não convencionais e estão em desacordo com os padrões de uso existentes. Ainda não está comprovado que isso agrega valor atenuante.
Aluan Haddad
1
Então, pessoal, também estou aqui pelo mesmo motivo, mas deixe-me acrescentar alguns pontos a esta discussão com esta questão sobre matriz de URL e google analytis na página do github da equipe angular 2: github.com/angular/angular/issues/11740 But após algumas pesquisas, a notação da matriz de URL parece ser mais legível por humanos que os parâmetros de consulta de URL , principalmente quando precisamos de algum parâmetro no meio ou no URL (não apenas no final).
Richard Lee
8
Acho que todo mundo que pensa que isso não é padrão também não está familiarizado com as especificações do modelo de uri? Codificar objetos complexos em parâmetros de caminho é um recurso muito útil dos modelos de uri; só porque a maioria das pessoas não conhece ou não usa isso não significa que seja uma conspiração maligna dos desenvolvedores angulares injetar complexidade inútil em sua vida.
Ajax
2
Pffft - "<coisa que eu não sabia que existia até agora> não é padrão , preservando assim a aceitabilidade da minha ignorância". O que a TBL fez ou não decidiu fazer com uma ideia é em grande parte irrelevante. Não era um recurso da web dele em 2001. Os recursos da web são os que os implementadores de clientes e servidores escolherem. Se o Angular suportar parâmetros de matriz e o JAX-RS os suportar e estas forem as ferramentas de implementação escolhidas, vá em frente e use o que funciona.
Dave